-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
error: charset malformed JSON... this happen with columns fields from db with specials characters... any fix? #8
Comments
I found a line that seems to solve this issue of Malformed JSON when the field contains special UTF-8 chars... if I change the Persistence_SQL.php and add the line below it fix the issue for the API JSON but for the Model edit in ATK4 it creates the problem with these fields showing wrong encoding... change to Persistence_SQL.php added this line to fix the API but it affects the Model... case 'text':
$v = utf8_encode($v);
break; Anyone knows how to fix it in the API only without affecting the ATK4 Model edit mode for those fields? |
Can you please try adding
Please report back if this helps you and I will include this fix in repo code then. |
First of all I installed the API using composer and checking the link you sent me it is a different API.php file than the one I installed via composer.. mine was having 368 lines... I have added too these line JSON_UNESCAPED_UNICODE you mentioned me before and it did not work either... I tried with your version of API.php and added the JSON_UNESCAPED_UNICODE and still the problem persist... Error again the same: Fatal error: Uncaught InvalidArgumentException: Unable to encode data to JSON in Zend\Diactoros\Response\JsonResponse: Malformed UTF-8 characters, possibly incorrectly encoded in /vendor/zendframework/zend-diactoros/src/Response/JsonResponse.php:164 Stack trace: #0 can you test it first with text fields in my case those text fields are: $this->addField('description_en', ['type' => 'text']); I have English not problem, I have italian, French and German and I have the problem.. the table that has these columns is collation utf8_general_ci and every field is defined with collation utf8_general_ci In ATK4 in edit mode the field are rendered OK and the character are well saved in the db... showing perfect but in the API the JSON gives this error... I put back also the Persistence_SQL.php to its normal code taking out the lines I have added and the problem it is the same: Fatal error: Uncaught InvalidArgumentException: Unable to encode data to JSON in Zend\Diactoros\Response\JsonResponse: Malformed UTF-8 characters, possibly incorrectly encoded in /vendor/zendframework/zend-diactoros/src/Response/JsonResponse.php:164 Stack trace: #0 adding this | JSON_UNESCAPED_UNICODE in those lines: https://github.com/atk4/api/blob/develop/src/Api.php#L240 does not fix the problem yet... |
can you verify if your Persistence_SQL.php it is like mine here? public function _typecastLoadField(Field $f, $value)
{
// LOB fields return resource stream
if (is_resource($value)) {
$value = stream_get_contents($value);
}
// work only on copied value not real one !!!
$v = is_object($value) ? clone $value : $value;
switch ($f->type) {
case 'integer':
$v = (int) $v;
break;
case 'float':
$v = (float) $v;
break;
case 'money':
$v = round($v, 4);
break;
case 'boolean':
if (isset($f->enum) && is_array($f->enum)) {
if (isset($f->enum[0]) && $v == $f->enum[0]) {
$v = false;
} elseif (isset($f->enum[1]) && $v == $f->enum[1]) {
$v = true;
} else {
$v = null;
}
} else {
$v = (bool) $v;
}
break;
case 'date':
case 'datetime':
case 'time':
$dt_class = isset($f->dateTimeClass) ? $f->dateTimeClass : 'DateTime';
$tz_class = isset($f->dateTimeZoneClass) ? $f->dateTimeZoneClass : 'DateTimeZone';
if (is_numeric($v)) {
$v = new $dt_class('@'.$v);
} elseif (is_string($v)) {
// ! symbol in date format is essential here to remove time part of DateTime - don't remove, this is not a bug
$format = ['date' => '+!Y-m-d', 'datetime' => '+!Y-m-d H:i:s', 'time' => '+!H:i:s'];
$format = $f->persist_format ?: $format[$f->type];
// datetime only - set from persisting timezone
if ($f->type == 'datetime' && isset($f->persist_timezone)) {
$v = $dt_class::createFromFormat($format, $v, new $tz_class($f->persist_timezone));
if ($v === false) {
throw new Exception(['Incorrectly formatted datetime', 'format' => $format, 'value' => $value, 'field' => $f]);
}
$v->setTimeZone(new $tz_class(date_default_timezone_get()));
} else {
$v = $dt_class::createFromFormat($format, $v);
if ($v === false) {
throw new Exception(['Incorrectly formatted date/time', 'format' => $format, 'value' => $value, 'field' => $f]);
}
}
// need to cast here because DateTime::createFromFormat returns DateTime object not $dt_class
// this is what Carbon::instance(DateTime $dt) method does for example
if ($dt_class != 'DateTime') {
$v = new $dt_class($v->format('Y-m-d H:i:s.u'), $v->getTimeZone());
}
}
break;
case 'array':
// don't decode if we already use some kind of serialization
$v = $f->serialize ? $v : json_decode($v, true);
break;
case 'object':
// don't decode if we already use some kind of serialization
$v = $f->serialize ? $v : json_decode($v, false);
break;
}
return $v;
} I added those lines I mentioned firstly because without them the problem exists at least for the API trying to create the JSON. I do not understand why 'TEXT' type does not exist in the type definition inside _typecastLoadField function this works for the API if I add it but then stop working will in ATK4 in edit mode when editing this text fields with special characters...
or this too
but then in ATK4 modifying the Persistence_SQL.php in those lines adding this lines of code above in edit mode shows then strange symbols and this is logical because in ATK4 the fields are will rendered all the time but in the API those fields does not render will if the have special characters... so until now I do not find still the correct solution when using the API with ATK4... |
OK I will make a testcase on my local machine and test this better in next few days and get back to you. Btw, how your composer.json looks like? |
thanks for having the time to test it! I wait... for the compose.json I have this on the root of ATK4/composer.json folder: I do not see why atk4/data is not listed there ... { } |
So here is fully featured test case - no problem found.
Output:
|
I have a table with a column text with French and Spanish characters and the JSON returned from the API gives me error
I think the issue it is the charset problem... my table is utf-8 charset in the db and header and html charset is ok but the issue it is from the API returning malformed Json when the column has accents in the field to show...
is there a way to set charset when using the line below?
$db = new \atk4\data\Persistence_SQL connection here?
or where?
thanks
The text was updated successfully, but these errors were encountered: