I need to be able to set my object like this:
$obj->foo = 'bar';
then I need to use it as an array like that:
if($obj['foo'] == 'bar'){
//more code here
}
I need to be able to set my object like this:
$obj->foo = 'bar';
then I need to use it as an array like that:
if($obj['foo'] == 'bar'){
//more code here
}
A quick way to do this is:
$obj = json_decode(json_encode($array));
Explanation
json_encode($array)
will convert the entire multi-dimensional array to a JSON string. (php.net/json_encode)
json_decode($string)
will convert the JSON string to a stdClass
object. If you pass in TRUE
as a second argument to json_decode
, you'll get an associative array back. (php.net/json_decode)
I don't think the performance here vs recursively going through the array and converting everything is very noticeable, although I'd like to see some benchmarks of this. It works, and it's not going to go away.
Actually, this can be done. Through a php extension.
File: config.m4
PHP_ARG_ENABLE(test, whether to enable test Extension support, [ --enable-test Enable test ext support]) if test "$PHP_TEST" = "yes"; then AC_DEFINE(HAVE_TEST, 1, [Enable TEST Extension]) PHP_NEW_EXTENSION(test, test.c, $ext_shared) fi
File: php_test.h
#ifndef PHP_TEST_H #define PHP_TEST_H 1 #define PHP_TEST_EXT_VERSION "1.0" #define PHP_TEST_EXT_EXTNAME "test" PHP_FUNCTION(getaddress4); PHP_FUNCTION(getaddress); extern zend_module_entry test_module_entry; #define phpext_test_ptr &test_module_entry #endif
File: test.c
#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_test.h" ZEND_BEGIN_ARG_INFO_EX(func_args, 1, 0, 0) ZEND_END_ARG_INFO() static function_entry test_functions[] = { PHP_FE(getaddress4, func_args) PHP_FE(getaddress, func_args) {NULL, NULL, NULL} }; zend_module_entry test_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif PHP_TEST_EXT_EXTNAME, test_functions, NULL, NULL, NULL, NULL, NULL, #if ZEND_MODULE_API_NO >= 20010901 PHP_TEST_EXT_VERSION, #endif STANDARD_MODULE_PROPERTIES }; #ifdef COMPILE_DL_TEST ZEND_GET_MODULE(test) #endif PHP_FUNCTION(getaddress4) { zval *var1; zval *var2; zval *var3; zval *var4; char r[500]; if( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aaaa", &var1, &var2, &var3, &var4) == FAILURE ) { RETURN_NULL(); } sprintf(r, "n%p - %p - %p - %pn%p - %p - %p - %p", var1, var2, var3, var4, Z_ARRVAL_P(var1), Z_ARRVAL_P(var2), Z_ARRVAL_P(var3), Z_ARRVAL_P(var4) ); RETURN_STRING(r, 1); } PHP_FUNCTION(getaddress) { zval *var; char r[100]; if( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &var) == FAILURE ) { RETURN_NULL(); } sprintf(r, "%p", Z_ARRVAL_P(var)); RETURN_STRING(r, 1); }
Then all you have to do is phpize it, config it, and make it. Add a "extension=/path/to/so/file/modules/test.so" to your php.ini file. And finally, restart the web server, just in case.
<?php $x = array("123"=>"123"); $w = $x; $y = $x; $z = &$x; var_dump(getaddress4($w,$x,$y,$z)); var_dump(getaddress($w)); var_dump(getaddress($x)); var_dump(getaddress($y)); var_dump(getaddress($z)); ?>
Returns(at least for me, your memory addresses will probably be different)
string ' 0x9efeb0 - 0x9effe0 - 0x9ef8c0 - 0x9efeb0 0x9efee0 - 0x9f0010 - 0x9ed790 - 0x9efee0' (length=84) string '0x9efee0' (length=8) string '0x9f0010' (length=8) string '0x9ed790' (length=8) string '0x9efee0' (length=8)
Thanks to Artefacto for pointing this out, but my original code was passing the arrays by value, so thereby was recreating arrays including the referenced-one, and giving you bad memory values. I have since changed the code to force all params to be passed by reference. This will allow references, arrays, and object, to be passed in unmolested by the php engine. $w/$z are the same thing, but $w/$x/$y are not. The old code, actually showed the reference breakage and the fact that the memory addresses would change or match when all variables were passed in vs multiple calls to the same function. This was because PHP would reuse the same memory when doing multiple calls. Comparing the results of the original function would be useless. The new code should fix this problem.
FYI - I'm using php 5.3.2.
You can try below code to merge array. Code generates desired output required to you. I have used sample array as given by you:
<?php
$arr1=array(
"384"=>array("name"=>"SomeMovieName1","age"=>"12.2 hrs","IMDBLink"=>"","IMDBRating"=>"", "coverArt"=>""),
"452"=>array("name"=>"SomeMovieName2","age"=>"15.2 hrs","IMDBLink"=>"","IMDBRating"=>"", "coverArt"=>""),
"954"=>array("name"=>"SomeMovieName3","age"=>"4.2 hrs","IMDBLink"=>"","IMDBRating"=>"", "coverArt"=>"")
);
$arr2=array(
"384" => array("IMDBLink" => "7.2", "IMDBRating" => "http://www.imdb.com/LinkToMovie1", "coverArt" => "http://www.SomeLinkToCoverArt.com/1"),
"452" => array("IMDBLink" => "5","IMDBRating" => "http://www.imdb.com/LinkToMovie2", "coverArt" => "http://www.SomeLinkToCoverArt.com/2"),
"954"=>array("IMDBLink" => "8","IMDBRating" => "http://www.imdb.com/LinkToMovie3", "coverArt" => "http://www.SomeLinkToCoverArt.com/3")
);
$arr3 = array();
foreach($arr1 as $key=>$val)
{
$arr3[] = array_merge($val, $arr2[$key]);
}
echo "<pre>";
print_r($arr3);
?>
As far as I can tell, there is no prebuilt solution for this, so you can just roll your own:
function array_to_object($array) {
$obj = new stdClass;
foreach($array as $k => $v) {
if(strlen($k)) {
if(is_array($v)) {
$obj->{$k} = array_to_object($v); //RECURSION
} else {
$obj->{$k} = $v;
}
}
}
return $obj;
}
Try extending ArrayObject
You'll also need to implement a
__get
Magic Method as Valentin Golev mentioned.Your class will need to looks something like this: