Why this code return null?
I check it but there is no error, And when i am call array merge with 2 default array Like ["x"=>"y","foo"=>"bar"] it work well!
See:
<?php
class ClassName
{
private $dataArray = array();
public function put($arr){
$this->dataArray = array_merge($arr,$this->dataArray);
return $this;
}
public function run(){
echo json_encode($this->dataArray);
}
}
$json = new ClassName();
$json->Test->LastLog = '123456789123456';
$json->Password = 'Mypassword';
$json->Dramatic = 'Cat';
$json->Things = array("HI" => 1, 2, 3);
$json->put($json)->run();
You Passed an object not array try like this code you got result:
$json->put((array)$json)->run();
Output is:
> {"\u0000ClassName\u0000dataArray":["Volvo XC90","BMW
> M4","MaclarenP1"],"Test":"123456789123456","Password":"Mypassword","Dramatic":"Cat","Things":{"HI":1,"0":2,"1":3},"0":"Volvo
> XC90","1":"BMW M4","2":"MaclarenP1"}
EDIT
If you want to pass the $json->Test->LastLog like this means you need to alternate you object declaration like:
$json = new ClassName();
$json->Test = array('LastLog'=>'123456789123456');
$json->Password = 'Mypassword';
$json->Dramatic = 'Cat';
$json->Things = array("HI" => 1, 2, 3);
Because in your put function is array_merge expecting array but you sent a json_object instead of array. (array) is act like json_decode...
Example: Simple Object
$object = new StdClass;
$object->foo = 1;
$object->bar = 2;
var_dump( (array) $object );
Output:
array(2) {
'foo' => int(1)
'bar' => int(2)
}
Related
I have an original array which is getting modified like e.g.
private function test()
{
$myArray = array(1,2,3);
$array = $this->modifyArray($myArray, 1);
}
private function modifyArray($paramArray, $someValue)
{
foreach ($paramArray as &$item) {
$item += $someValue;
}
return $paramArray;
}
To my understanding $myArray and $array will be [2,3,4] at the end of function 'test'.
But what is the correct approach if I want to re-do this and call modifyArray again like:
private function test()
{
$myArray = array(1,2,3);
$array = $this->modifyArray($myArray, 1);
// new call
$anotherArray = $this->modifyArray($myArray, 2);
}
To my understanding $myArray, $array and $anotherArray will now be [4,5,6] and not $array = [2,3,4] and $anotherArray = [3,4,5] which is my intention.
Or am I totally misguided here?
You are misguided here. The variable $paramArray inside modifyArray exists only inside modifyArray and is not modified. It only returns the changed array back. This means:
$myArray = array(1,2,3); // will still be [1,2,3]
$array = $this->modifyArray($myArray, 1); // $array will be [2,3,4], because [1,2,3] is passed
// new call
$anotherArray = $this->modifyArray($myArray, 2); // $anotherArray will be [3,4,5] because [1,2,3] is passed
If you want another behavior, you should link $paramArray to the passed array with &:
private function modifyArray(&$paramArray, $someValue)
Now the result would be:
$myArray = array(1,2,3); // will still be [1,2,3]
$array = $this->modifyArray($myArray, 1); // $array will be [2,3,4], because [1,2,3] is passed and $myArray is now [2,3,4]
// new call
$anotherArray = $this->modifyArray($myArray, 2); // $anotherArray will be [4,5,6] because [2,3,4] is passed and $myArray is now [4,5,6]
When creating a object in php used to return JSON is it possible to add a property and force it to go at the top? I'd like this since the object is exposed via an API and it is nice to have ids at the top.
For example:
$obj = new stdClass();
$obj->name = 'John';
$obj->age = 26;
$obj->id = 3645;
When you json_encode() this, it turns into:
{
"name": "John",
"age": 26,
"id": 3645
}
Is there a way to force id at the top of the object even though it is added last? Note, I can't simply just add id before adding name and age because of other dependent code.
It's easily possible if you use an associative array instead of an object, i.e.
$x = ['name' => 'john', 'age' => 26]; // or: $x = (array)$obj
$x = ['id' => 123] + $x;
echo json_encode($x);
// {"id":123,"name":"john","age":26}
However, it's important to note that in JSON property ordering is not defined and should not be relied upon. If what you currently have works, this change would be rather useless in fact.
Not very elegant but...
$obj = new stdClass();
$obj->name = 'John';
$obj->age = 26;
$obj->id = 3645;
$name = $obj->name;
$age = $obj->age;
unset($obj->name);
unset($obj->age);
$obj->name = $name;
$obj->age = $age;
echo json_encode($obj);
Hmm, nice question!
It is not possible to add a property and force it to go at the top.
You have to sort the object properties or the array keys.
Some nitpicking here: JSON is unordered by definition, but the browsers respect the insertion order. More: https://code.google.com/p/v8/issues/detail?id=164
JSON
4.3.3 Object An object is a member of the type Object. It is an unordered collection of properties each of which contains a
primitive value, object, or function. A function stored in a property
of an object is called a method.
Check this out: http://ideone.com/Hb4rGQ
<?php
function array_reorder_keys($array, $keynames){
if(empty($array) || !is_array($array) || empty($keynames)) return;
if(!is_array($keynames)) $keynames = explode(',',$keynames);
if(!empty($keynames)) $keynames = array_reverse($keynames);
foreach($keynames as $n){
if(array_key_exists($n, $array)){
$newarray = array($n=>$array[$n]); //copy the node before unsetting
unset($array[$n]); //remove the node
$array = $newarray + array_filter($array); //combine copy with filtered array
}
}
return $array;
}
$obj = new stdClass();
$obj->name = 'John';
$obj->age = 26;
$obj->id = 3645;
function get_json_sorted($object, $array) {
return json_encode(array_reorder_keys(get_object_vars($object), $array));
}
var_dump(get_json_sorted($obj, array('id', 'name', 'age')));
This is a solution. Turn the object into an assoc array. Get the last item (both key and value) off of the array (I'm assuming id is the last element) and move it to the front. Finally convert the assoc array back into an object.
$data_array = json_decode(json_encode($obj), true);
if(is_array($data_array)) {
end($data_array);
$data_array = array_merge(array(key($data_array) => array_pop($data_array)), $data_array);
$data = json_decode(json_encode($data_array), false);
}
This is a similar answer to Jacks' answer ( https://stackoverflow.com/a/24900322/6312186 ) but that caused a fatal error for me. I had to tweak it a bit by casting to array, using array_merge() and cast back to object, but this worked nicely for me:
$obj = (object) array_merge( (array)$obj2, (array)$obj);
This code is more generic and should work for all versions of PHP, including strict mode. Full code here
$obj = new stdClass(); // create new object
$obj->name = 'john';
$obj->age = '26';
$obj2 = new stdClass(); // we want to add this object to the top of $obj
$obj2->id = 'uid2039';
$obj = (object) array_merge( (array)$obj2, (array)$obj);
var_dump($obj);
// object(stdClass)#8700 (3) { ["id"]=> string(7) "uid2039" ["name"]=> string(4) "john" ["age"]=> string(2) "26" }
If you are json_encodeing this, you don't need to cast it back to an object again before encoding it:
$arr = ['name' => 'John', 'age' => '26'];
echo json_encode($arr);
// {"name":"john","age":"26"}
// is the same as:
$obj = (object)$arr;
echo json_encode($obj );
// {"name":"john","age":"26"}
Because this seems like what I have to do to get this effect:
$arr = ['a'=>'first', 'b'=>'second', ...];
$iter = new ArrayIterator( $arr );
// Do a bunch of iterations...
$iter->next();
// ...
$new_iter = new ArrayIterator( $arr );
while( $new_iter->key() != $iter->key() ) {
$new_iter->next();
}
Edit: Also, just to be clear, should I NOT be modifying the base array with unset()? I figure the array iterator stores its own copy of the base array, so using offsetUnset() doesn't seem right.
ArrayIterator does not implement a tell() function, but you can emulate this, and then use seek() to go to the position you want. Here's an extended class that does just that:
<?php
class ArrayIteratorTellable extends ArrayIterator {
private $position = 0;
public function next() {
$this->position++;
parent::next();
}
public function rewind() {
$this->position = 0;
parent::rewind();
}
public function seek($position) {
$this->position = $position;
parent::seek($position);
}
public function tell() {
return $this->position;
}
public function copy() {
$clone = clone $this;
$clone->seek($this->tell());
return $clone;
}
}
?>
Use:
<?php
$arr = array('a' => 'first', 'b' => 'second', 'c' => 'third', 'd' => 'fourth');
$iter = new ArrayIteratorTellable( $arr );
$iter->next();
$new_iter = new ArrayIteratorTellable( $arr );
var_dump($iter->current()); //string(6) "second"
var_dump($new_iter->current()); //string(6) "first"
$new_iter->seek($iter->tell()); //Set the pointer to the same as $iter
var_dump($new_iter->current()); //string(6) "second"
?>
DEMO
Alternately, you can use the custom copy() function to clone the object:
<?php
$arr = array('a' => 'first', 'b' => 'second', 'c' => 'third', 'd' => 'fourth');
$iter = new ArrayIteratorTellable( $arr );
$iter->next();
$new_iter = $iter->copy();
var_dump($iter->current()); //string(6) "second"
var_dump($new_iter->current()); //string(6) "second"
?>
DEMO
The only solution I thought of is using a copy of current array
$arr = ['a'=>'first', 'b'=>'second'];
$iter = new ArrayIterator( $arr );
// Do a bunch of iterations...
$iter->next();
var_dump($iter->current());
// ...
$arr2 = $iter->getArrayCopy();
$new_iter = new ArrayIterator( $arr2 );
while( $new_iter->key() != $iter->key() ) {
var_dump($new_iter->current());
$new_iter->next();
}
PHP has a function extract that will convert an array like this:
$array = array(
'var1' => 1,
'var2' => 2
);
to:
$var1 = 1;
$var2 = 2;
now, I need the opposite, i have few variables:
$var3 = 'test';
$test = 'another';
$datax = 1;
that needs to be:
$array = array(
'var3' => 'test',
'test' => 'another',
'datax' => 1
);
Is there something like this in PHP?
You can use compact() to achieve this.
$var3 = 'test';
$test = 'another';
$datax = 1;
$array = compact('var3', 'test', 'datax');
Reference: http://php.net/manual/en/function.compact.php
like this
$preDefined = (get_defined_vars());
$var3 = 'test';
$test = 'another';
$datax = "1";
$newDefined = array_diff(get_defined_vars(), $preDefined);
print_r($newDefined);
$array = get_defined_vars()
See get_defined_vars()
You'd have to be really sure you wanted to do this (it includes things in the global scope automatically) but you can use
$my_vars = get_defined_vars();
If you want it more selective than that, you could look at filtering it like this:
$my_vars = pack_vars(get_defined_vars())
function pack_vars ($defined_vars)
{
$packed = array();
$ignored = array('dont_use_this', 'ignored_var', 'ignore_this_too');
foreach ($defined_vars AS $key => $value)
{
if (!in_array($key, $ignored))
{
$packed[$key] = $value;
}
}
return $packed;
}
How do I merge all the array items into a single string?
Use the implode function.
For example:
$fruits = array('apples', 'pears', 'bananas');
echo implode(',', $fruits);
Try this from the PHP manual (implode):
<?php
$array = array('lastname', 'email', 'phone');
$comma_separated = implode(",", $array);
echo $comma_separated; // lastname, email, and phone
// Empty string when using an empty array:
var_dump(implode('hello', array())); // string(0) ""
?>
If you are trying to just concatenate all of strings in the array, then you should look at implode().
$array1 = array(
"one",
"two",
)
$array2 = array(
"three",
"four",
)
$finalarr = array_merge($array1, $array2);
$finalarr = implode(",", $finalarr);
will produce this one,two,three,four
You can use join. It's an alias for implode, and in my opinion more readable:
$fruits = array('apples', 'pears', 'bananas');
echo join(',', $fruits);
join(" -- ", Array("a", "b")) == "a -- b"
actually join is an alias for the implode function.
If you want to merge the string representation of a group of objects into a single string, you can use implode on an array of those objects. The objects' classes just have to have the __toString() magic method defined.
class myClass {
protected $name;
protected $value;
public function __construct($name,$value) {
$this->name = $name;
$this->value = $value;
}
public function __toString() {
return $this->name . '/' . $this->value;
}
}
$obj1 = new myClass('one',1);
$obj2 = new myClass('two',2);
$obj_array = array($obj1, $obj2);
$string_of_all_objects = implode('|',$obj_array);
echo $string_of_all_objects; // 'one/1|two/2'
I found that trick useful to quickly get a string representation of a group of objects for display on a webpage. No need to loop through the object array with foreach and using echo $obj->get('name').
EDIT: And here's and example with a "collection" class. I have 2 outputs (echos) at the end. The 2nd one should work, but I'm not sure about the 1st.
class myCollectionClass implements IteratorAggregate {
protected $objects = array();
public function __construct() {};
public function add(myClass $object) {
$this->objects[] = $object;
return $this; // fluid
}
public function getIterator() { // for the interface
return new ArrayIterator($this->objects);
}
public function __toString() {
return implode($this->objects);
}
}
$my_collection = new myCollectionClass();
$my_collection->add($obj1)->add($obj2); // add both myClass objects to the collection. can do in one line because fluid
//echo implode('|',$my_collection); // Comment out myCollectionClass's __toString method to test this. does it work? I'm not sure. But the next line will work thanks to myCollectionClass' __toString, which itself uses myClass's __toString
echo $my_collection; // same output as previous block before EDIT.
$array= array( "Alfred Hitchcock", "Stanley Kubrick", "Martin Scorsese", "Fritz Lang" );
$string="";
foreach ( $tempas $array) {
$string=$string.",".$temp;
}
foreach($array as $key => $value) {
$string .= $value .' ';
}
For Multi Array such as:
$multi_arrays = array(
0 => array('model' => 'Product 1'),
1 => array('model' => 'Product 2'),
2 => array('model' => 'Product 3'),
3 => array('model' => 'Product 4'));
$pattern = array('/\[/', '/\]/', '/{"model":/', '/}/', '/\"/');
$str_models = preg_replace($pattern, '', json_encode( $multi_arrays));
The result will be:
Product 1, Product 2, Product 3, Product 4
You can change pattern for get any result you want!