I have code like :
$result = $object->property[0];
but I want to do something like :
if ($a) {
$property = 'blue' }
else {
$property = 'black'}
$result = $object->$property[0];
However this give me a Cannot use string offset as an array error.
Any pointers (no pun intended) appreciated.
Use braces:
$result = $object->{$property}[0];
$result = $object->{$property}
Related
I have an object which is an array of JSON objects. Kinda Like this,
$object = [
{
"id":1,
"name":"blue",
"order":4
},
{
"id":2,
"name":"green",
"order":6
},
{
"id":3,
"name":"yellow",
"order":2
}
]
I wanted to access the properties in a simple way and a single line maybe like this,
Say if I wanted the "order" of the object with name "blue"
$blue_order = $object[something]->[name="blue"]->order;
Kinda mixed Jquery in this. But I hope you understand. Right now the best I've got is this,
for($i=0; $i<count($object); $i++){
if($object[$i]->name == "blue"){
$blue_order = $object[$i]->order;
}
}
This seems very inefficient though and I don't want to use a loop because the array is very large and looping through it will be very slow. So how do I do this?
I used a "for" loop instead of foreach because the array can be null. And also the order of the array elements will not always be the same.
So I can't do something like
$object[0]->order
<?php
$arr = array(
array('id'=>1,'name'=>'blue','order'=>4),
array('id'=>2,'name'=>'green','order'=>6),
array('id'=>3,'name'=>'yellow','order'=>2),
);
// $json is JSON version of the arrays in $arr
$json = json_encode($arr);
// show $json
echo $json . "\n";
// create arrays from JSON so it can be used in PHP easier
$obj = json_decode($json);
$color = 'blue';
$blue_order = array_filter($obj, function($i) use ($color) { return $i->name == $color; })[0]->order;
echo "Blue Order: " . $blue_order;
You may be able to use array_filter to help this become a one-liner. I included the json_decode and json_encode so I could have a complete example.
You could still use foreach but check if the array isn't empty first, like this:
if(!empty($object)){
foreach($object as $element){
if($element->name == "blue"){
$blue_order = $element->order;
}
}
}
Also, your code looks efficient to me, what I would probably add is a break after you find the value, like this:
if(!empty($object)){
foreach($object as $element){
if($element->name == "blue"){
$blue_order = $element->order;
break;
}
}
}
If your object has a lot of information and you're going to do a lot of searches, then you could do some pre-processing so it get easier to search, like this:
$object_by_name = array();
if(!empty($object)){
foreach($object as $element){
$object_by_name[$element->name] = $element;
}
}
Then, you could search it like this:
if(!empty($object_by_name['blue'])){
$blue_order = $object_by_name['blue']->order
}
Keep it simple.
You're writing way too much code.
$array_list = ($array_list)?:[];
$array_list = array_filter($array_list,function($var) {
return ($var->name=="blue");
});
$order = ($array_list)? $array_list[0]->order :'';
I have the following a PHP object with the following properties:
Object:
-Advanced
--Data
To access it in PHP I would have to do the following:
$object->Advanced->Data
Now I want to define a string which has a syntax like this:
$string = "Advanced->Data";
How do I proceed from here to be able to use:
$object->$string = "Something";
So that in the end
$object->Advanced->Data = "Something";
I couldn't figure out using eval or $object->{$string}
If I try to use $object->$string
PHP creates a new property called "Advanced->Data", basically not interpreting the -> Operator.
Though it is a hack, try this, it should work for your case
$arr = array();
$arr['Advanced']['Data'] = 'something';
$string = json_decode(json_encode($arr), 0);
echo $string->Advanced->Data;
Though it is a hack, this can also fetch your desire
$string = &$object->Advanced->Data;
$string = "here we go";
var_dump($object->Advanced->Data);
Probably eval() is not best solution, but it can be useful in your case:
class obj2 {
public $Data = 'test string';
}
class obj1 {
public $Advanced;
public function __construct() {
$this->Advanced = new obj2();
}
}
$test = new obj1();
$string1 = "\$test->Advanced->Data = 'new string';";
$string2 = "\$result = \$test->Advanced->Data;";
eval($string1);
eval($string2);
echo $result . PHP_EOL;
Output will be "new string".
Once try this,
$string = "Advanced->Data";
$arr = explode("->",$string);
$temp = $object->{$arr[0]}->$arr[1];
But this is specific condition. Let me know your requirement if this is not the answer.
Is it possible to create a variable variable pointing to an array or to nested objects? The php docs specifically say you cannot point to SuperGlobals but its unclear (to me at least) if this applies to arrays in general.
Here is my try at the array var var.
// Array Example
$arrayTest = array('value0', 'value1');
${arrayVarTest} = 'arrayTest[1]';
// This returns the correct 'value1'
echo $arrayTest[1];
// This returns null
echo ${$arrayVarTest};
Here is some simple code to show what I mean by object var var.
${OBJVarVar} = 'classObj->obj';
// This should return the values of $classObj->obj but it will return null
var_dump(${$OBJVarVar});
Am I missing something obvious here?
Array element approach:
Extract array name from the string and store it in $arrayName.
Extract array index from the string and store it in $arrayIndex.
Parse them correctly instead of as a whole.
The code:
$arrayTest = array('value0', 'value1');
$variableArrayElement = 'arrayTest[1]';
$arrayName = substr($variableArrayElement,0,strpos($variableArrayElement,'['));
$arrayIndex = preg_replace('/[^\d\s]/', '',$variableArrayElement);
// This returns the correct 'value1'
echo ${$arrayName}[$arrayIndex];
Object properties approach:
Explode the string containing the class and property you want to access by its delimiter (->).
Assign those two variables to $class and $property.
Parse them separately instead of as a whole on var_dump()
The code:
$variableObjectProperty = "classObj->obj";
list($class,$property) = explode("->",$variableObjectProperty);
// This now return the values of $classObj->obj
var_dump(${$class}->{$property});
It works!
Use = & to assign by reference:
$arrayTest = array('value0', 'value1');
$arrayVarTest = &$arrayTest[1];
$arrayTest[1] = 'newvalue1'; // to test if it's really passed by reference
print $arrayVarTest;
In echo $arrayTest[1]; the vars name is $arrayTest with an array index of 1, and not $arrayTest[1]. The brackets are PHP "keywords". Same with the method notation and the -> operator. So you'll need to split up.
// bla[1]
$arr = 'bla';
$idx = 1;
echo $arr[$idx];
// foo->bar
$obj = 'foo';
$method = 'bar';
echo $obj->$method;
What you want to do sounds more like evaluating PHP code (eval()). But remember: eval is evil. ;-)
Nope you can't do that. You can only do that with variable, object and function names.
Example:
$objvar = 'classObj';
var_dump(${$OBJVarVar}->var);
Alternatives can be via eval() or by doing pre-processing.
$arrayTest = array('value0', 'value1');
$arrayVarTest = 'arrayTest[1]';
echo eval('return $'.$arrayVarTest.';');
eval('echo $'.$arrayVarTest.';');
That is if you're very sure of what's going to be the input.
By pre-processing:
function varvar($str){
if(strpos($str,'->') !== false){
$parts = explode('->',$str);
global ${$parts[0]};
return $parts[0]->$parts[1];
}elseif(strpos($str,'[') !== false && strpos($str,']') !== false){
$parts = explode('[',$str);
global ${$parts[0]};
$parts[1] = substr($parts[1],0,strlen($parts[1])-1);
return ${$parts[0]}[$parts[1]];
}else{
return false;
}
}
$arrayTest = array('value0', 'value1');
$test = 'arrayTest[1]';
echo varvar($test);
there is a dynamic approach for to many nested levels:
$attrs = ['level1', 'levelt', 'level3',...];
$finalAttr = $myObject;
foreach ($attrs as $attr) {
$finalAttr = $finalAttr->$attr;
}
return $finalAttr;
Let me first start off, sorry for the confusing title. I didn't know how to exactly describe it but here goes. So I am querying a database for string. If there is only 1 result found then it is relatively easy to create an array, fill it with information, encode JSON and return that. I am confused as to when there are multiple results. The code below is what I am using but I highly doubt it is correct. I can't encode it into JSON format using my method which is what I need. If you can help at least point me in the correct direction, I would be more than grateful! Thank you!
PHP:
if ($action == 'profile') {
while ($pson = mysql_fetch_array($personQuery)) {
$typeSearch = 'profile';
$profQuery = mysql_query("SELECT * FROM tableName WHERE ColumnName LIKE '$query'");
$compQuery = mysql_query("SELECT * FROM tableName2 WHERE ColumnName LIKE '$query'");
if ($profQuery && mysql_num_rows($profQuery) > 0) {
$personQueryRows = mysql_num_rows($profQuery);
while ($row = mysql_fetch_array($profQuery)) {
if ($compQuery && mysql_num_rows($compQuery) > 0) {
while ($com = mysql_fetch_array($compQuery)) {
if (mysql_num_rows($profQuery) > 1) {
$compQueryRows = mysql_num_rows($compQuery);
if ($compQueryRows > 0) {
$compReturn = "true";
} else {
$compReturn = "false";
}
$nameArray = Array(
"success"=>"true",
"date"=>date(),
"time"=>$time,
"action"=>$action,
"returned"=>"true"
);
global $result;
for ($i=1;$i<=$personQueryRows;$i++) {
$nameResult[$i]=Array(
"id"=>$row['id'],
"name"=>$row['name'],
"gender"=>$row['gender'],
"comp"=>$row['company'],
"queryType"=>"profile"
);
$result = array_merge($nameArray, $nameResult[$i]);
}
$encodedJSON = json_encode($result);
echo $encodedJSON;
}
}
}
}
}
}
}
}
Returned JSON:
{"success":"true","date":"Jun 29 2012","time":"14:43:16","action":"profile","returned":"true","id":"14321","name":"John Smith","gender":"male","comp":"ABC Studios, LLC.","queryType":"profile"}
{"success":"true","date":"Jun 29 2012","time":"14:43:16","action":"profile","returned":"true","id":"292742","name":"John Smith","gender":"male","comp":"DEF Studios, LLC.","queryType":"profile"}
JavaScript error (when parsing JSON):
Uncaught SyntaxError: Unexpected token {
P.S. I am just getting started with PHP Arrays, and JSON formatting so I apologize if this is totally wrong. Still in the learning phase.
It looks like you're building up $nameResult[$i], but then you do:
$result = array_merge($nameArray, $nameResult[$i]);
You're doing that in each iteration of that for loop (once for each of the rows you got back), meaning that each time, you're clobbering $result.
After you finish that for loop, you then take whatever $result finally is (meaning the last $personQueryRows), and then json_encode it.
Looking at your other question (http://stackoverflow.com/questions/11257490/jquery-parse-multidimensional-array), it looks like what you should really be doing is before the loop where you go over $personQueryRows:
$output=$nameArray;
And then replace the array_merge line with:
$output[] = $nameResult[$i];
That last line will append the $result array onto the $output array as a new array member, meaning that it's nesting the array, which is what you'll need for your nested JSON.
Your code should look like this:
global $result;
$result = array();
.......
if ($action == 'profile') {
while{{{{{{{{...}}}}}}}}}}}
$encodedJSON = json_encode( $result );
echo $encodedJSON;
}
I read php document and I saw this:
class foo{
var $bar = 'I am a bar';
}
$foo = new foo();
$identity = 'bar';
echo "{$foo->$identity}";
And I saw somebody wrote like this:
if (!isset($ns->job_{$this->id})){
//do something
}
But when I tried with this code, It didn't work:
$id1 = 10;
$no = 1;
echo ${id.$no};
Can you guys tell me why it didn't work and when I can use braces with variable correctly?
Live example
Brackets can be used on object types, for instance, to simulate a array index. Supposing that $arr is an array type and $obj an object, we have:
$arr['index'] ===
$obj->{'index'}
You can make it more fun, for instance:
$arr["index{$id}"] ===
$obj->{"index{$id}"}
Even more:
$arr[count($list)] ===
$obj->{count($list)}
Edit: Your problem --
variable of variable
// Your problem
$id1 = 10;
$no = 1;
$full = "id{$no}";
var_dump($$full); // yeap! $$ instead of $
What are you expecting?
$id = 10;
$no = 1;
echo "${id}.${no}"; // prints "10.1"