2

Estoy tratando de poder obtener información, (con el fin de brindar una Api), en el cual la obtengo usando odbc_fetch_object, pero no logro realizar una petición GET y me devuelva la información que necesito. Los datos se consultan y se procesan en un Controller.

La base de datos donde se consulta es una tabla .dbf, utilizo VisualFoxProDriver para lograr la conexión.

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Queries\ApiSQL;

class ApiController extends Controller
{
    public function indexPersonal()
    {
        $ODBCdriver = $this->ODBCdriver;
        $ODBCuser = $this->ODBCuser;
        $ODBCpwd = $this->ODBCpwd;

        $query = new ApiSQL;

        $conID = odbc_pconnect($ODBCdriver, $ODBCuser, $ODBCpwd);

        define('personal', @odbc_exec($conID, $query->queryPersonal()));

        $jsonData = array();
        while ($array = odbc_fetch_object(personal)) {
            $jsonData[] = $array;
        }
        
        dd($jsonData);

        return response()->json($jsonData, 200);
    }
}

Esta es la información que obtengo de dd($jsonData);:

introducir la descripción de la imagen aquí

Pero cuando quiero obtener los datos sin hacer dd($jsonData);

Laravel me devuelve el siguente error (en el navegador ):

InvalidArgumentException Malformed UTF-8 characters, possibly incorrectly encoded

Si el Controller lo utilizo de la siguente manera, puedo obtener los datos correctamente, pero no me convence para nada porque tengo que escribir una linea por cada columna.

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Queries\ApiSQL;

class ApiController extends Controller
{
    public function indexPersonal()
    {
        $ODBCdriver = $this->ODBCdriver;
        $ODBCuser = $this->ODBCuser;
        $ODBCpwd = $this->ODBCpwd;

        $query = new ApiSQL;

        $conID = odbc_pconnect($ODBCdriver, $ODBCuser, $ODBCpwd);

        define('personal', @odbc_exec($conID, $query->queryPersonal()));

        while ($row = odbc_fetch_array(personal)) {
            $data[$row['id']] = array(
                'pers_codi' => utf8_encode($row['id']),
                'pers_lega' => utf8_encode($row['legajo']),
                'pers_nomb' => utf8_encode($row['name']),
                'pers_domi' => utf8_encode($row['domicilio']),
                'pers_loca' => utf8_encode($row['localidad']),
        );
        };
        return response()->json($data, 200);
    }
}

Este es el resueltado que obtengo en Postman del código

introducir la descripción de la imagen aquí

Me gustaria poder utilizar la primera opción, pero no puedo dar en la tecla. Si tienen alguna pista, les agradecería.

Gonzalo Piñeiro
  • 165
  • 1
  • 1
  • 11
  • ¿Y el archivo fuente que codificación tiene? – BetaM Jul 30 '20 at 03:02
  • Es evidente que hay un problema en la codificación. La mejor solución es encontrar a qué nivel se encuentra el problema para solucionarlo de raíz. En mi respuesta a [esta pregunta](https://es.stackoverflow.com/q/59489/29967) he tratado de abordar situaciones como la tuya de una manera global. Es muy probable que en tu caso se resuelva aplicando utf-8 al objeto de la conexión. – A. Cedano Jul 30 '20 at 14:03
  • Y si usas json_encode Y json_decode y evitas de usar utf-8 encode? json_encode tiene varias modalidades para formatear. – toto Jul 30 '20 at 15:55

1 Answers1

2

Las bases de datos de FoxPro (DBase) generalmente tienen una codificación ASCII (o similar) y json_encode() requiere que los datos estén en UTF-8, por eso obtienes el error.

No tienes que crear una línea para cada elemento del arreglo, solo necesitas una función que lo haga por ti:

// Envías un arreglo a la función 
function arr2utf8($arr) {
    // Recorres cada elemento para codificar su valor en utf8
    foreach($arr as $key => $val) {
        $arr[$key] = utf8_encode($val);
    }
    // Devuelves el arreglo codifificado
    return $arr;
}

Cuando necesites codificar el contenido de un arreglo, simplemente llamas a la función:

    while ($row = odbc_fetch_array(personal)) {
        // Codificas antes de comenzar a asignar
        $row = arr2utf8($row);
        $data[$row['id']] = array(
            // Asignas como lo haces normalmente
            'pers_codi' => $row['id'],
            'pers_lega' => $row['legajo'],
            'pers_nomb' => $row['name'],
            'pers_domi' => $row['domicilio'],
            'pers_loca' => $row['localidad'],
        );
    };
    // Esto ya no va a generar error
    return response()->json($data, 200);
Triby
  • 23,274
  • 3
  • 13
  • 35
  • Perfecto. Era muy simple, solamente iterando en el array y codificando cada elemento. Con esto puedo obtener un array con objetos dentro. Muchas gracias – Gonzalo Piñeiro Jul 30 '20 at 18:48