I'm working with a third-party class, and I need to be able to run a section of code one of two ways, depending...
$reader->get()->first()->each(function($obj)
{
// Do stuff
}
OR
$reader->get()->each(function($obj)
{
// Do stuff
}
I've always been able to call properties variably with something like...
$a = 1;
$obj->{"$a"}
But unfortunately the below doesn't work...
if (some scenario)
{
$a = "get()->first()";
}
else
{
$a = "get()";
}
$reader->{"$a"}->each(function($obj)
My problem is i'm not sure how to phrase the question for google...I'm assuming there's a solution for the above problem.
Thanks in advance for any help!
You can only use ->{$variable} for the names of properties and methods of the class itself, you can't put PHP syntax like -> in there. What you can do is use function variables:
function get_all($reader) {
return $reader->get();
}
function get_first($reader) {
return $reader->get()->first();
}
$a = 'get_all'; // or $a = 'get_first';
$a($reader)->each(function($obj) {
// do stuff
});
Alternative to Barmar's answer, which imho is a bit clearer.
$it = function($obj) {
// do stuff
});
if (some_scenario) {
$reader->get()->first()->each($it);
} else {
$reader->get()->each($it);
}
One more solution:
if (some_scenario) {
$foo = $reader->get()->first();
} else {
$foo = $reader->get();
}
$foo->each(function($obj) {
// do stuff
});
Is it possible to return an array, but also tell php it's supposed to mean false?
Example:
if ($res = a_function()) {
// all good
}
else {
echo getErrorByNumber($res['err_no']);
}
a_function:
function a_function() {
// do fancy stuff
if (xy) return true;
return array('err_no' => 1);
}
I guess its not possible, since php will always take an array for return true, right?
Lot's of ways. Probably the preferred one, compare to true with type checking ===:
if(($res = a_function()) === true) {
// all good
}
else {
echo getErrorByNumber($res['err_no']);
}
A non-empty array will always be true:
if($res = a_function() && !is_array($res)) {
// all good
}
else {
echo getErrorByNumber($res['err_no']);
}
Or flip it around:
if(is_array($res)) { //or isset($res['err_no'])
echo getErrorByNumber($res['err_no']);
}
else {
// all good
}
I would solve this problem with a byref parameter:
function foo(&$errors)
{
if (allWentWell())
{
$errors = null;
return true;
}
else
{
$errors = array('err_no' => 007);
return false;
}
}
// call the function
if (foo($errors))
{
}
else
{
echo getErrorByNumber($errors['err_no']);
}
This way you do not have to distinguish between different possible return types and you will not run into type juggling problems. It is also more readable, you know what's inside the $errors variable without documentation. I wrote a small article explaining why mixed-typed return values can be so dangerous.
How to exclude a variable from being required in a function?
IE:
function foo($name,$address,$pizza_preference,$date)
{
if(!$pizza_preference)
{
return array($name,$address,$date);
}
else
{
return array($name,$address,$pizza_preference,$date);
}
}
When calling this function how would I set it up so $pizza_preference is not required, but optional? So that if you only entered 3 arguments in the function it omits $pizza_preference, or would I have to make it so when you enter 0 it just doesn't return it?
Just define a default value for it. Then you can use that function without passing a value:
function foo($name,$address,$date,$pizza_preference=null)
{
if(!$pizza_preference)
{
return array($name,$address,$date);
}
else
{
return array($name,$address,$pizza_preference,$date);
}
}
Usually you put variables that have default values at the end of the parameters list so you don't have to include blank parameters when calling the function.
See Default argument values on the PHP website for more.
UPDATE
If you're going to have multiple parameters with default values and want to be able to skip them individually you can pass an array as the only parameter and read the values from there:
function foo(array $parameters)
{
if(!$parameters['pizza_preference'])
{
return array($parameters['name'],$parameters['address'],$parameters['date']);
}
else
{
return array($parameters['name'],$parameters['address'],$parameters['date'],$parameters['pizza_preference']);
}
}
I recommend (and I always do) to pass arguments as Object..
function foo($params)
{
if(!$params->pizza_preference)
{
return array($pizza_preference->name,$pizza_preference->address,$pizza_preference->date);
}
else
{
return array($pizza_preference->name,$pizza_preference->pizza_preference->address,$pizza_preference,$pizza_preference->date);
}
}
Sample usage:
$p1 = new stdClass;
$p1->name = 'same name';
$p1->address ='same address';
$p1->pizza_preference = '1';
$p1->date = '26-04-2012';
$p2 = new stdClass;
$p2->name = 'same name';
$p2->address ='same address';
$p2->date = '26-04-2012';
foo($p1); //will return the first array
foo($p2); //will return the second array
Well youll need to change the signature... anything not required should go last:
function foo($name, $address, $date, $pizza_preference = null) {
}
You can set default values in the function declaration:
function foo($name,$address,$date,$pizza_preference=null)
{
if($pizza_preference === null)
{
return array($name,$address,$date);
}
else
{
return array($name,$address,$pizza_preference,$date);
}
}
As an alternative approach, you can use an associative array as a single argument, and then just check it inside the function like this:
function foo($args) {
$name = (!empty($args['name']) ? $args['name'] : NULL);
$address = (!empty($args['address']) ? $args['address'] : NULL);
$pizza_preference = (!empty($args['pizza_preference']) ? $args['pizza_preference'] : NULL);
$date = (!empty($args['date']) ? $args['date'] : NULL);
}
I cannot figure out why this function is not working. Evertime I try to make the recursive call all I get is an IE page with a cannot display error message. I left // by the lines that is causing me the trouble. I also tried the call without the $this-> and got an error function not recognized
private function insert($key, $current) {
$newnode=new Node($key);
$parent=$this->root;
if($this->root==null) {
$this->root=$newnode;
return;
} else {
if($newnode->data > $parent->data) {
$parent=$parent->rightChild;
$this->insert($key, $parent);//if I comment this line it
//work, but that make the function useless
} else {
echo "smaller ";
}
}
}
The error is obviously an infinite recursive loop.
This is most probably due to the fact that you never use the $current argument.
You're always comparing the $newnode->data against $this->root->data which if greater once, will always be greater.
Update
Here's how I'd change it
private function insert($key, $current = null)
{
$newnode = new Node($key);
$parent = null === $current ? $this->root : $current;
if (null === $parent) {
$this->root = $newnode;
return;
}
if ($newnode->data > $parent->data) {
// same as before from here
I am not an expert Wordpress PHP developer but I am not understanding this situation. I am passing a variable through a static function into the $GLOBALS variable that contains an array. That variable when in the static function is always NULL, but before it goes into it, it is a valid type and prints fine.
functions.php
$badge_Id = get_comment_meta($comment->comment_ID,"badge_id", true);
if(strlen($badge_Id) > 0) {
Cisco_Rewards::add_badge_id($badge_id);
echo $badge_id; // PRINTS PERFECTLY
}
rewards.php
class Cisco_Rewards {
static function add_badge_id($badge_id) {
if(count($GLOBALS['badge_ids']) == 0) {
$GLOBALS['badge_ids'] = array();
}
echo $badge_id; // WONT PRINT, IS NULL
array_push($GLOBALS['badge_ids'], $badge_Id);
print_r($GLOBALS['badge_ids']); // ALWAYS HAS NULL VALUES
}
Instead of
if(count($GLOBALS['badge_ids']) == 0) {
$GLOBALS['badge_ids'] = array();
}
echo $badge_id;
try
var_dump($badge_id); // to check what it contains at the very beginning of the function
if(!is_array($GLOBALS['badge_ids'])) {
$GLOBALS['badge_ids'] = array();
}