Is it possible for the PHP json_encode function do not convert empty string values to null?
UPDATE
I can not replicate this behaviour in clear conditions, and looks like it's already a default for this function.
This is already the default behavior.
json_encode(['test' => '']);
generates:
{"test":""}
No that i know of, but you could do this:
array_walk_recursive($value, function (&$item, $key) {
$item = null === $item ? '' : $item;
});
Related
So I'm trying to implement php-etl to my application and MySQL doesnt let me insert null to nullable integer but it does if I manually change it, like this:
### This works ###
foreach($data as $row){
if($row["some_integer"] == Null){
$row["some_integer"] = Null;
}
if($row["some_other_integer"] == Null){
$row["some_other_integer"] = Null;
}
MyModel::create($row);
}
### This throws General error: 1366 Incorrect integer value ###
foreach($data as $row){
MyModel::create($row);
}
Tried both manually and with marquine/php-etl package. The input is csv file, null is empty space between ;; separators. Anybody knows what is going on here? Working on laravel 7.
Ok so the package loads the values as empty strings and by setting it Null it becomes real null... Is there a way to quicky convert these values to null?
MySQL won't treat an empty string as null, simply because an empty string and null are two different things. So the message you get from MySQL isn't weird, it's correct.
Nullify all empty strings in an array
If you just want to nullify all empty strings in an array, you can create a simple function for it:
function nullifyEmptyStrings(array $array)
{
return array_map(function ($item) {
return $item !== '' ? $item : null;
}, $array);
}
Then call it where ever/when ever you need it:
$row = nullifyEmptyStrings($row);
or use it directly in the argument for the create function:
MyModel::create(nullifyEmptyStrings($row));
Here's a demo
Nullify specific empty strings in an array
If you want to be able to define which array items to nullify, you can use this function:
function nullifyEmptyArrayValues(array $array, array $keys)
{
foreach ($keys as $key) {
if (array_key_exists($key, $array) && $array[$key] === '') {
$array[$key] = null;
}
}
return $array;
}
And in your code, you first pass the array containing the data and then another array with the keys to nullify, if the values are empty:
$row = nullifyEmptyArrayValues($row, ['some-key', 'another-key']);
Here's a demo
So I've got a while loop, inside I have $array_collections that gives me 35 value per loop, I want to verify for every value if it's equal to NULL then give it an empty string. I did that :
while ($array_collections = tep_db_fetch_array($query)) {
foreach ($array_collections as $key => $value) {
if (is_null($value)) {
$array_collections[$key] = "";
}
}
$docs[] = new \Elastica\Document('', \Glam\HttpUtils::jsonEncode(
array(
'X' => $array_collections['X'],
... etc
)));
}
This technically should work, but the loop goes over 500K elements so it's huge, and for every element we put it into a table, problem is that I run out of memory at some point. So is there another simple way to give any given NULL value an empty string without looping?
well, you can put NOT NULL constraint with empty string as DEFAULT value in the DB for that so you dont need to do that in php using looping, but if you dont want to change the DB design then you can use COALESCE in your query
select COALESCE(yourfield,'') from table
it will convert NULL value into empty string
You can use array_map function to replace null values into empty string.
$array_collections=array_map(function($ar)
{
if(isset($ar) && $ar!=null){
return $ar;
}
return '';
},$array_collections);
Above code replace all null values to empty string. No need of loop.
you can use array_walk:
function replace_null(&$lsValue, $key) {
if(is_null($lsValue)) {
$lsValue = "";
}
}
array_walk($array_collections, 'replace_null');
I'm working with a large array. We're displaying all fields of data in the array with a table. Some fields in the array are null because the user hasn't accumulated anything in that field. However, we wanted a zero for when they have such a result. Our solution was to display the value along with intval()
intval(#$users[$user_id]['loggedin_time'])
Which is fine, but it is ugly and inelegant. Is there a way, without a foreach loop, to set all values of '' in the array to be 0?
Yes, with array_map:
$input = array(...);
$output = array_map(function($item) { return $item ?: 0; }, $input);
The above example uses facilities of PHP >= 5.3 (inline anonymous function declaration and the short form of the ternary operator), but you can do the same in any PHP version (only perhaps more verbosely).
You should think a bit about the conditional inside the callback function; the one I 'm using here will replace all values that evaluate to false as booleans with zeroes (this does include the empty string, but it also includes e.g. null values -- so you might want to tweak the condition, depending on your needs).
Update: PHP < 5.3 version
It's either this:
function callback($item) {
return $item == false ? 0 : $item;
}
$output = array_map('callback', $input);
Or this:
$output = array_map(
create_function('$item', 'return $item == false ? 0 : $item;'),
$input);
I assume you are retrieving this information from a database of some sort.
If you are getting the array from a Mysql Table try something like this:
http://forums.mysql.com/read.php?20,36579,36579#msg-36579
I've been doing some tests with $_SESSION variables and that left a lot of them set to NULL, but still existing. I can remove them one-by-one, but how can I just loop through the $_SESSION array and remove NULL variables quickly?
You can use array_filter with a callback function that uses is_null:
$output = array_filter($input, function($val) { return !is_null($val); });
$_SESSION = array_filter($_SESSION, 'count');
Will have the effect of removing all NULL values (since count() returns 0 for NULL) and also any countable (either an array or an object) that has 0 elements, from the PHP manual:
Returns the number of elements in var,
which is typically an array, since
anything else will have one element.
If var is not an array or an object
with implemented Countable interface,
1 will be returned. There is one
exception, if var is NULL, 0 will be
returned.
Since 0 evaluates to false in a boolean context there is no need to implement any custom function.
This will remove NULL values, but not other empty or FALSE. Easily modified if you also want rid of FALSE vals and empty strings, etc.
foreach ($_SESSION as $key=>$var)
{
if ($var === NULL) unset($_SESSION[$key]);
}
$_SESSION = array_filter($_SESSION);
This will remove any "falsy" values from the session array, including null.
That should do it:
foreach ($_SESSION as $key => $value)
{
if ($value === NULL)
unset($_SESSION[$key];
}
P.S. array_filter will remove anything equal to "false". You should provide your own callback function or use this example if you need to remove only NULL-values and keep empty strings or zeros.
foreach($_SESSION as $key => $value){
if(empty($value) || is_null($value)){
unset($_SESSION[$key]);
}
}
If you are "deleting" $_SESSION elements by setting value to NULL, you are doing it wrong. To unset array element you should use
unset
on $_SESSION element.
# Wrong
$_SESSION['foo'] = NULL;
#Good
unset($_SESSION['foo']);
I am returning a json_encode() of an array of objects pulled from an ORM. It includes lots of properties with a null value. What is the neatest way to remove these properties that are null? I guess I could iterate over the properties, look if they are null and then unset() that property, but surely there must be a more elegant way?
Try this; it will only work on a simple object, but if it's coming from an ORM it should be simple enough.
// Strips any false-y values
$object = (object) array_filter((array) $object);
Thanks to Gordon's answer to another question yesterday for giving me the idea.
This works by
converting the object to an associative array, where object properties are the keys and their values are the array values
using array_filter with default arguments to remove array entries with a false (e.g. empty, or null) values
converting the new array back to a simple object
Note that this will remove all properties with empty values, including empty strings, false boolean values and 0s, not just nulls; you can change the array_filter call if you want to keep those and only remote those that are exactly null.
// Strips only null values
$object = (object) array_filter((array) $object, function ($val) {
return !is_null($val);
});
I'm going to add to the response given by El Yobo because that will only work if you have a 1 dimensional object or array. If there is any array or object nesting then in order to get the accepted solution to work you must create some sort of recursive array filter. Not good.
The best solution my colleague and I came up with was to actually perform a regular expression on the JSON string before it was returned from the server.
$json = json_encode($complexObject);
echo preg_replace('/,\s*"[^"]+":null|"[^"]+":null,?/', '', $json);
The regular expression will remove all places in the string of the form ,"key":null including any whitespace between the leading comma and the start of the key. It will also match "key":null, afterwards to make sure that no null values were found at the beginning of a JSON object.
This obviously isn't the most ideal situation but it will effectively remove null entries without having to develop some kind of recursive array filter.
Despite the name you can also use array_walk with a closure:
// Setup
$obj = (object) array('foo' => NULL, 'bar' => 'baz');
// equivalent to array_filter
array_walk($obj, function($v,$k) use ($obj) {
if(empty($v)) unset($obj->$k);
});
// output
print_r($obj);
Output
stdClass Object
(
[foo] => bar
)
There's no standard function to remove null-valued properties. Writing one of your own isn't inelegant, if you write one elegantly.
I made this function that solves my problem: clean null 'object properties' and 'array properties' inside an object. Also, you can have many 'levels' of objects/arrays inside of an object:
function cleanNullsOfObject(&$object) {
foreach ($object as $property => &$value) {
if (is_object($value)) {
cleanNullsOfObject($value);
if (empty(get_object_vars($value))) {
unset($object->$property);
}
}
if (is_array($value) && is_object($value[0])) {
foreach ($value as $val) {
cleanNullsOfObject($val);
}
}
if (is_null($value) || (is_array($value) && empty($value))) {
unset($object->$property);
}
}
}
//test
$object = new stdClass();
$object->property = "qwe";
$object->nullProperty = null;
$propertyObject = new stdClass();
$propertyObject->property = "asd";
$propertyObject->nullProperty = null;
$object->propertyObject = $propertyObject;
var_dump($object);
echo "<br>";
echo "<br>";
cleanNullsOfObject($object);
var_dump($object);
Building off of #Gordon 's answer, a couple of adjustments would be needed to make that work, but you can also use array_walk_recursive instead. The reference is required or otherwise any changes you make to the object won't apply to the scope outside of the Closure.
IE:
$someObject = (array)$someObject;
array_walk_recursive($someObject, function($v,$k) use (&$someObject) {
if($someObject[$k] == null) {
unset($someObject[$k]);
}
});
$someObject = (object)$someObject;
var_dump($someObject);