A script running on on our live server sends out data from the following line:
$log_output .= '<br>'.__LINE__.'<br>recordings_data='.var_export($recordings_data,TRUE);
Which looks like this:
recordings_data=stdClass::__set_state(array( 'RecordingLongResponse'
=> array ( 0 => stdClass::__set_state(...), 1 => stdClass::__set_state(), 2 => stdClass::__set_state(), 3 =>
stdClass::__set_state(array( 'roomStartDate' => '1321977120000',
'roomEndDate' => '1321977120000', 'recordingURL' => 'serverURL1',
'secureSignOn' => false, 'recordingId' => '1287268130290',
'creationDate' => '1321977120000', 'recordingSize' => '6765975',
'roomName' => 'Stakeholder Analysis', 'sessionId' => '1287268130229',
)), ...), ))
I'm not sure how to 'recreate' the object. I tried unserializing it:
$recording_data_ser= file_get_contents('elm-ser-data.txt'); // where I've saved everything after the '='
$recording_data = unserialize($recording_data_ser);
serialize() and unserialize() are the generally accepted methods for dumping/loading PHP objects. You can also do it with json_encode() and json_decode(). Is there a reason you want to use var_export()?
Edit: you can only unserialize() the result of serialize() - var_dump() is in a completely different format and isn't designed for importing unless you use eval().
For example:
$arr = array('foo' => 'bar');
var_export($arr);
#=> array (
#=> 'foo' => 'bar',
#=> )
echo serialize($arr);
#=> a:1:{s:3:"foo";s:3:"bar";}
echo json_encode($arr);
#=> {"foo":"bar"}
Once you have the serialized data (via serialize() or json_encode()), you can use the opposite method (unserialize() or json_decode(), respectively) to recreate the object again.
var_export() is intended to dump a data structure to a file. You then have to eval() or include() or require() that file. the serialize() format is completely different from var_export.
var_export produces valid PHP code to define a data structure, as if you'd written out the array/object definition yourself. serialize/unserialize write out in a completely different format, and they're not interchangeable.
If you call var_export() on an instance of stdClass, it attempts to export it using ::__set_state(), which, for some reason, is not implemented in stdClass.
However, casting an associative array to an object usually produces the same effect (at least, it does in my case). So I wrote an improved_var_export() function to convert instances of stdClass to (object) array () calls. If you choose to export objects of any other class, I'd advise you to implement ::__set_state() in those classes.
<?php
/**
* An implementation of var_export() that is compatible with instances
* of stdClass.
* #param mixed $variable The variable you want to export
* #param bool $return If used and set to true, improved_var_export()
* will return the variable representation instead of outputting it.
* #return mixed|null Returns the variable representation when the
* return parameter is used and evaluates to TRUE. Otherwise, this
* function will return NULL.
*/
function improved_var_export ($variable, $return = false) {
if ($variable instanceof stdClass) {
$result = '(object) '.improved_var_export(get_object_vars($variable), true);
} else if (is_array($variable)) {
$array = array ();
foreach ($variable as $key => $value) {
$array[] = var_export($key, true).' => '.improved_var_export($value, true);
}
$result = 'array ('.implode(', ', $array).')';
} else {
$result = var_export($variable, true);
}
if (!$return) {
print $result;
return null;
} else {
return $result;
}
}
// Example usage:
$obj = new stdClass;
$obj->test = 'abc';
$obj->other = 6.2;
$obj->arr = array (1, 2, 3);
improved_var_export((object) array (
'prop1' => true,
'prop2' => $obj,
'assocArray' => array (
'apple' => 'good',
'orange' => 'great'
)
));
/* Output:
(object) array ('prop1' => true, 'prop2' => (object) array ('test' => 'abc', 'other' => 6.2, 'arr' => array (0 => 1, 1 => 2, 2 => 3)), 'assocArray' => array ('apple' => 'good', 'orange' => 'great'))
*/
// Example implementation in context of OP
$export = improved_var_export($data, true);
file_put_contents(dirname(__FILE__).'/data.php', '<'.'?php return '.$export.'; ?'.'>');
// "Unserialization" (evaluation)
$import = include dirname(__FILE__).'/data.php';
?>
Related
I just created a small program to check JSON and JSON_FORCE_OBJECT
$tree = [
0 => array
(
'id' => 1,
'parent' => '0',
'name' => 'b',
'surname' => 'myfolder/b'
),
1 => array
(
'id' => 2,
'parent' => 1,
'name' => 'ignore',
'surname' => 'myfolder/ignore2'
),
2 => array
(
'id' => 3,
'parent' => 1,
'name' => 'ignore2',
'surname' => 'myfolder/ignore4'
)
];
var_dump($tree);
$try = json_encode($tree);//To print with key. Also if we decode we get result as object
//echo $try;
echo '<br />';
$try2 = json_decode($try,JSON_FORCE_OBJECT);
var_dump($try2);
$try2 is exactly equal to $tree an associative array.
Whereas if I remove JSON_FORCE_OBJECT from this line
$try2 = json_decode($try,JSON_FORCE_OBJECT);
I get an array with child object. Though JSON_FORCE_OBJECT is supposed to be used with json_encode but using it with json_decode, I get a surprising result. I am unable to understand whats going on inside?? I thought when I encode it and decode it I should get same result. But I got the same result only when I used JSON_FORCE_OBJECT. Can anyone please help why this happens?
According to the manual: http://php.net/manual/en/function.json-decode.php
json_decode returns an array of objects if you want to convert them in assoc array you should specify the second param which is a boolean
JSON_FORCE_OBJECT is an int with value 16...
when this is passed as second param php cast/converts it to its bool equivalent which true.
To test the above stated behavior try:
var_dump((bool)1; (bool)2, (bool)16)
//output bool(true) bool(true) bool(true) .
var_dump((bool)0)
//outputs bool(false)
So it's nothing to do with JSON_FORCE_OBJECT...even
json_decode($try,true);
json_decode($try,2);
json_decode($try,3);
json_decode($try,4);
json_decode($try,'someVar');
....
//should return your expected result (assoc array)
Similarly if you pass 0 as second param PHP will cast it into bool (which is false) and returns you an object
json_decode($try,0);
json_decode($try,false);
json_decode($try,null)
json_decode($try)
...
//will return objects
The second parameter to json_decode is a boolean. It accepts true or false. It does not accept JSON_FORCE_OBJECT. You're trying to use the wrong constant for the wrong function.
json_decode's 4th parameter accepts a bitmask of constants, but currently it only supports JSON_BIGINT_AS_STRING.
If you want to return stdClass instances for JSON objects from json_decode, set its second parameter to false (the default). Setting it to any non-falsey value makes it return associative arrays instead of objects. Setting it to JSON_FORCE_OBJECT counts as "not-falsey".
It's all described in the manual: http://php.net/json_decode
I have started to understand the 2D array and multi-dimensional array, some reference books mentioned it has different ways to declare them. Which methods will be declare the array more easier and easy to understand?
method 1:
$pgmCode = array
(
"Item1"=>array("...","..."=>array("..."=>1)),
......
)
Or method2:
$A['ABC']['...'] = '3';
$A['...']['...']['...'] = '2';
Furthermore, if I will build a database and calling the data as array store, which method will be preferred to use?
Thanks.
$pgmCode = array(
"item1" = array(
"subItem1" => true,
"subItem2" => array("subSubItem1", "subSubItem2"),
),
"item2" = array(
"subItem1" => true,
"subItem2" => array("subSubItem1", "subSubItem2"),
),
);
Watchout with mixed use of array and string item in an array, if you will do a in_array() on a mixed variable array it will always return true if you don't use the strict mode of the function.
in your method 1
in_array("something", $pgmCode['Item1']); //return true
in_array("something", $pgmCode['Item1'], true); //return false
$pgmCode = array
(
"Item1"=>array("...","..."=>array("..."=>1)),
"Item1"=>array("...","..."=>array("..."=>1)),
......
);
makes it more understandable.
I have the following code for generating a new array:
$languages = array_keys(['French'=>4, 'Spanish'=>2, 'German'=>6, 'Chinese'=>8]);
function generateLanguageRules($language)
{
return ["seatsAllocatedFor$language"=>"numeric|max:300"];
}
array_map('generateLanguageRules', $languages);
//Output:
array(
0 => array(
'seatsAllocatedForFrench' => 'numeric|max:300'
),
1 => array(
'seatsAllocatedForSpanish' => 'numeric|max:300'
),
2 => array(
'seatsAllocatedForGerman' => 'numeric|max:300'
),
3 => array(
'seatsAllocatedForChinese' => 'numeric|max:300'
)
)
I'm wondering if there is an easier way to output a flat array, instead of a nested one? I'm using Laravel. Are there maybe some helper functions that could do this?
UPDATE:
One possible Laravel specific solution:
$languages = array_keys(['French'=>4, 'Spanish'=>2, 'German'=>6, 'Chinese'=>8]);
$c = new Illuminate\Support\Collection($languages);
$c->map(function ($language){
return ["seatsAllocatedFor$language"=>"numeric|max:300"];
})->collapse()->toArray();
I dont know if laravel has a built-in method for that, (haven't used it yet). But alternatively, you could use RecursiveArrayIterator in conjunction to iterator_to_array() to flatten it and assign it. Consider this example:
$languages = array_keys(['French'=>4, 'Spanish'=>2, 'German'=>6, 'Chinese'=>8]);
function generateLanguageRules($language) {
return ["seatsAllocatedFor$language"=>"numeric|max:300"];
}
$data = array_map('generateLanguageRules', $languages);
$data = iterator_to_array(new RecursiveIteratorIterator(new RecursiveArrayIterator($data)));
echo "<pre>";
print_r($data);
echo "</pre>";
Sample Output:
Array
(
[seatsAllocatedForFrench] => numeric|max:300
[seatsAllocatedForSpanish] => numeric|max:300
[seatsAllocatedForGerman] => numeric|max:300
[seatsAllocatedForChinese] => numeric|max:300
)
I have a problem: I need to turn an array into a string and pass it to a function for debugging output.
I cannot directly output the string with print_r, I need to join it with some other strings and pass it to a function.
Google did not bring any results that display the array in a human-readable way without directly printing them. I need a string which I can pass to another function.
You can use the print_r() function like this:
$myarray = ['a', 'b', 'c'];
$string = print_r($myarray, true);
echo $string;
The optional boolean flag as second parameters makes the function return a string instead of directly sending it to the output.
print_r uses an optional parameter to set to true to return the string instead of outputting it :
$array = array('foo', 'bar', array('baz' => true, 'test' => 42));
$stringifiedArray = print_r($array, true);
/* $stringifiedArray == "
Array
(
[0] => foo
[1] => bar
[2] => Array
(
[baz] => 1
[test] => 42
)
)
"
*/
Otherwise, I can see two ways, but both are not as easily readable by a human :
json_encode :
$stringifiedArray = json_encode($array, true);
// $stringifiedArray == "["foo","bar",{"baz":true,"test":42}]"
serialize :
$stringifiedArray = serialize($array, true);
// $stringifiedArray == "a:3:{i:0;s:3:"foo";i:1;s:3:"bar";i:2;a:2:{s:3:"baz";b:1;s:4:"test";i:42;}}"
You could also try <?php implode(', ', $array); ?>
I'm trying to build a dynamic associative array value lookup function (within a class):
class Family
{
public static $members = array(
'one' => array(
'child' => 0,
'children' => 5
),
'two' => array(
'child' => 2,
'children' => null
)
);
public static function resolveMemberValue()
{
$chain = func_get_args();
$lookup = 'members' . '[\'' . implode('\'][\'', $chain) . '\']';
var_dump( $lookup );
return static::$$lookup;
}
}
Family::resolveMemberValue('one', 'child');
But this results in:
string(23) "members['one']['child']"
Fatal error: Access to undeclared static property: Family::$members['one']['child'] in /family.php on line 23
PHP Fatal error: Access to undeclared static property: Family::$members['one']['child'] in /family.php on line 23
Though, copying the dumped value, and pasting inside the script + appending dollar sign, it returns what's expected:
var_dump( Family::$members['one']['child'] );
int(0)
Reason why I need this is, because it will be used with multiple variables, and called from generator functions.
What is wrong with the snippet?
Variable variables only substitutes in a string for the name of the variable. It can't evaluate the content of that string (in this case the string members['one']['child'])
Your code is looking for a static property literally with the named $members['one']['child'] not an element of the static array $members.
Try this instead:
$member = static::$members[$chain[0]];
return $member[$chain[1]];
Also, I'd recommend not using func_get_args(), but explicitly naming your parameters in the method declaration. Some features of PHP a best left behind....
Oh, had to just tinker a little - managed to make a helper function.
The function replaces the implode() and the explicit key definition.
function array_lookup()
{
$chain = func_get_args();
$array = array_shift($chain);
foreach ($chain as $key) $array = $array[$key];
return $array;
}
$test = array(
'one' => array(
'child' => 0,
'children' => 5
),
'two' => array(
'child' => 2,
'children' => null
)
);
var_dump($test, 'one', 'child'); // int(0)
I have left out any kind of error checking for this example, but it does what I was looking for.
And yes, for my example, it nails it.