PHP array_map looping to itself - php

I´m creating an rest server using some examples in internet. The source is:
https://github.com/danucu/GUS/blob/master/restfulengine/restfulobj.php
The problem is when I´m making a call to the object, it calls itself again in the method getMyVars:
protected function getMyVars($myVars = null) {
if (empty($myVars)) {
$myVars = $this->showMyPublicsOnly();
}
if (is_array($myVars)) {
/*
* Intorc array convertit la obiect
* utilizand __METHOD__ (constanta ;) )
* pentru apelurile recursive
*/
return array_map(__METHOD__, $myVars);
} else {
// intorc array
return $myVars;
}
}
The full rest object is here:
https://github.com/danucu/GUS/blob/master/restfulengine/usertest.php
When Whe I run localhost/rest/UserREST/example it runs in a infinite loop.
I have changed the method getMyWars to:
echo $this->method."\n\n";
echo __METHOD__."\n\n";
$arReturn = array_map(__METHOD__, $myVars);
print_r($arReturn);
And I got:
GET
restObject::getMyVars
...infinitely and it never reaches: print_r($arReturn);
Maybe I´m doing something wrong.

Well, that code looks really strange, it will always call itself to the end of the times (or at least until the call stack overflows). Let me explain:
if (is_array($myVars)) { //is_array === true
return array_map(__METHOD__, $myVars); // This will call __METHOD__ (getMyVars); and pass $myVars to it (which is an array).
} else { //This will never be reached.
return $myVars;
}

Your code apparently works. What I think is happening is this:
first call: getMyVars() get passed, say, null.
this is empty, so it gets $this->showMyPublicsOnly()
this is an array, so every member of that array gets applied getMyVars()...
...but one of those values is equivalent to empty.
So if you have, say,
[ 'varOne' => 'Hello', 'varTwo' => 'World', 'varThree' => 42 ];
it will work, but
[ 'varOne' => '', ]
will loop.
You can try this:
// Only iterate on non-empty values
$myVars = array_filter($myVars);
// If there are no non-empty values...
if (empty($myVars)) {
/* ...this would loop, so we return an empty array */
return [ ];
}
return array_map(__METHOD__, $myVars);

Related

PHP function return value disappears (?)

In the following function call the log files show me that
even though before the return call the variable has a value the variable receiving the return value is empty
the if empty has just been included because I didn't believe what is happening.
What am I missing? Any clou?
...
...
$workingProductArray=$this->placeNextItem($workingProductArray, ... );
if (empty($workingProductArray)){
write_log ("DYING array empty");
die(); //<-- and indeed the system dies.
}
}
private function placeNextItem(array $workingProductArray, ... )
{
if ($this->areAllProductsIgnored($workingProductArray)){
print_r($workingProductArray); // <-- SHOWS EXPECTED ARRAY AND VALUES
return $workingProductArray; // returning this value
}
Weird! Try to not print_r2 from placeNextItem function if still doesn't work try to name $workingProductArray to something else for placeNextItem.
I was just digging into the code. and I just noticed I made a terrible thinking mistake...
(which you can't see on the mentioned code... here the code to the function's end)
...
...
$workingProductArray=$this->placeNextItem($workingProductArray, ... );
if (empty($workingProductArray)){
write_log ("DYING array empty");
die(); //<-- and indeed the system dies.
}
}
private function placeNextItem(array $workingProductArray, ... ){
if ($this->areAllProductsIgnored($workingProductArray)){
print_r($workingProductArray); // <-- SHOWS EXPECTED ARRAY AND VALUES
return $workingProductArray; // returning this value
}
...
$this->placeNextItem(array $workingProductArray, ...);
}
So I call this function also from within (recursively), I thought the return statement would go to the method above but instead it goes (doh! off course!) back to it's recursive caller, which is the same method where I have to return the value too...
easy fix:
private function placeNextItem(array $workingProductArray, ... ){
if ($this->areAllProductsIgnored($workingProductArray)){
print_r($workingProductArray); // <-- SHOWS EXPECTED ARRAY AND VALUES
return $workingProductArray; // returning this value
}
...
return $this->placeNextItem(array $workingProductArray, ...);
}

Returning an array element value in php lower than php 5.4

I've a function which returns an array. To return the value of that array I do something like this:
$obj->methodname()[keyvalue];
This works in php 5.4 only. I want to make this code work in lower php versions.
My code:
class ObjectTest {
public $ar;
function __construct() {
$this->ar = array(
1 => 'beeldscherm',
2 => 'geluidsbox',
3 => 'toetsenbord',);
}
public function arr(){
return $this->ar;
}
}
$obj = new ObjectTest();
//by calling the method and putting square brackets and the key of the element
var_dump($obj->arr()[2]);
I've rewritten the code for lower versions like this:
public function arr($arg = null){
if(is_null($arg)){
return $this->ar;
}
return $this->ar[$arg];
}
I'm doubting if this solution is an elegant one. What would you say? Any better solutions?
You can do like, store array in a variable and than access particular array index.
$arrList = var_dump($obj->arr());
echo $arrList[2];

PHP array value isn't shown by var_dump but it was fetched.

I wrote some program to check the value in an array.
var_dump($profileuser);//NULL
$profileuser = get_user_to_edit($user_id);//fetch the value of $profileuser
var_dump($profileuser);//does not print the value of $profileuser->user_url
//nor by print_r($profileuser)
if(isset($profileuser->user_url))
echo $profileuser->user_url;//printed!!!!How is it possible??
Could somebody can explain how this happened?
background:
I modified the kernel of wordpress.
This happened when I modified the file of wp-admin/user-edit.php.
You say it's an array, but you're accessing it as an object ($obj->foo rather than $arr['foo']), so it's most likely an object (actually it is - get_user_to_edit returns a WP_User). It could easily contain the magic __get and __isset methods that would lead to this behaviour:
<?php
class User {
public $id = 'foo';
public function __get($var) {
if ($var === 'user_url') {
return 'I am right here!';
}
}
public function __isset($var) {
if ($var === 'user_url') {
return true;
}
return false;
}
}
$user = new User();
print_r($user);
/*
User Object
(
[id] => foo
)
*/
var_dump( isset($user->user_url) ); // bool(true)
var_dump( $user->user_url ); // string(16) "I am right here!"
DEMO
One possibility is that $profileuser is an Object that behaves as an array and not an array itself.
This is possible with interface ArrayAccess. In this case, isset() would return true and you might not see it when you do var_dump($profileuser);.
When you want an object to behave like an array, you need to implement some methods which tell your object what to do when people use it as if it were an array. In that case, you could even create an Object that, when accessed as an array, fetches some webservice and return the value. That may be why you are not seeing those values when you var_dump your variable.
I thinks it's not possible, I've created test code and var_dump behaves correctly. Are you 100% sure you don't have any typo in your code? I remind variables in PHP are case sensitive
<?php
$profileuser = null;
class User
{
public $user_url;
}
function get_user_to_edit($id) {
$x = new User();
$x->user_url = 'vcv';
return $x;
}
var_dump($profileuser);//NULL
$user_id = 10;
$profileuser = get_user_to_edit($user_id);//fetch the value of $profileuser
var_dump($profileuser);//does not print the value of $profileuser->user_url
//nor by print_r($profileuser)
if(isset($profileuser->user_url))
echo $profileuser->user_url;//printed!!!!How does it possible??
Result is:
null
object(User)[1]
public 'user_url' => string 'vcv' (length=3)
vcv

PHP: Return the last json object

Edit
Thanks for all the input on this, I did find error in my question so modifying now. Sorry for that.
I am trying to figure out how to return the last object in the JSON string I have rendered. The two functions I am working with:
public function revision($return = false)
{
$id = $this->input->post('galleryID');
$data = array('revision_count' => $this->revision->count_revision($id) );
if($return){
return json_encode($data);
}
else {
echo json_encode($data);
}
}
public function last_revision()
{
$allRevisions = json_decode($this->revision(),true);
return end($allRevisions);
}
The issue is that end() returns error stating that 1st parameter should be array.
Thanks for any help on this.
It is important to note here that json_decode returns an instance of stdClass by default. Try using json_decode($jsonstring, true) to return the JSON as a PHP associative array.
However, You haven't included what the $this->revision() method does. Could you possibly show that portion of the code, since that is the function you are getting a return value from?
Edit:
Alright, after we saw the right function in your code, here are a couple of things I would like to say:
You have added a $return parameter to your revision method, but you aren't using it when you need to. You should change $this->revision() to $this->revision(true) in your last_revision method.
If you're going to return data from the revision() method, there's not much of a point in json_encodeing it, just to json_decode the result. Just pass back the raw data array.
Once you have changed both of these things, this should work:
$allRevisions = $this->revision(true); return end($allRevisions['revision_count']);
You can change the edit_function() to:
public function edit_revision($return = false)
{
$galleryID = $this->input->post('galleryID');
$revisionID = $this->input->post('revisionID');
$data = array('revision_images' => $this->revision->get($galleryID, $revisionID) );
if($return)
return json_encode($data);
else
echo json_encode($data);
}
and then:
public function last_revision(true)
{
$allRevisions = json_decode($this->revision());
return end($allRevisions);
}
Maybe you need convert that json output to an php array (json_decode() function), then you could get the last item with array_pop() function:
https://php.net/array_pop

Directly display the value of an array returned by a method

Is it possible to do in one line calling a method that returns an array() and directly get a value of this array ?
For example, instead of :
$response = $var->getResponse()->getResponseInfo();
$http_code = $response['http_code'];
echo $http_code;
Do something like this :
echo $var->getResponse()->getResponseInfo()['http_code'];
This example does not work, I get a syntax error.
If you're using >= PHP 5.4, you can.
Otherwise, you'll need to use a new variable.
What you can do is to pass the directly to your function. Your function should be such that if a variable name is passed to it, it should the value of that variable, else an array with all variables values.
You can do it as:
<?php
// pass your variable to the function getResponseInfo, for which you want the value.
echo $var->getResponse()->getResponseInfo('http_code');
?>
Your function:
<?php
// by default, it returns an array of all variables. If a variable name is passed, it returns just that value.
function getResponseInfo( $var=null ) {
// create your array as usual. let's assume it's $result
/*
$result = array( 'http_code'=>200,'http_status'=>'ok','content_length'=>1589 );
*/
if( isset( $var ) && array_key_exists( $var, $result ) ) {
return $result[ $var ];
} else {
return $result;
}
}
?>
Hope it helps.
Language itself does not support that for an array.
In case you can change what getResponseInfo() return:
You can create simple class, which will have array as an constructor parameter. Then define magical getter which will be just pulling the keys from the instance array
function __get($key)
{
return #content[$key]
}
Then you'll be able to do
echo $var->getResponse()->getResponseInfo()->http_code;
// or
echo $var->getResponse()->getResponseInfo()->$keyWhichIWant;
What i wrote is just proposal. The real __get method should have some check if the exists and so

Categories