this is the code:
class university {
function hello($name){
return $this->name;
}
}
function compare1(&$obj1 , $obj2){
if ($obj1 === $obj2) {
return TRUE;
}else {
return FALSE;
}
}
}
$uni1 = new university();
$uni2 = new university();
$uni3 = $uni1;
echo compare1($uni1 , $uni3) ?"SAME" : "DIFFERENT";
I want to know why the output is SAME ,although the compare function take the first parameter by refrence and the second by value, so the identity operator must gives us FALSE.
Also if we try to make this:
$uni3 = clone $uni1;
echo compare1($uni1 , $uni3) ?"SAME" : "DIFFERENT";
the output is DIFFERENT .
knowing that both example are equal .right?
$uni3 = $uni1;
Here the value have been passed by reference, so of course when compare they are the same object.
$uni3 = clone $uni1;
Here you've made a shallow copy, so the references are different then the result will be not the same.
Related
This question already has answers here:
How to use return inside a recursive function in PHP
(4 answers)
Closed 9 months ago.
I have a problem with a recursive function in PHP which returns a JSON object. When the the condition is met to run the function a second time I always get an empty object as result {}. Everything is executed as it would be in the first run, but I always get an empty result.
Here is my code (very much simplified, yet functioning):
public function run()
{
$result = null;
// .......
// there is alot other stuff here, that all runs
// perfectly through also the second run
// ......
// Conditional Routing
if($this->wfProfile->autoprocess){
// select new wfProfile and go again.
$this->autoprocess(function($data){
if($data['error']==0){
$result = null;
$this->run(); // from here we start over !
}else{
return $data;
}
});
}else{
return ['error'=>0,'message'=>'all good']; // this is where it should go at the end of second loop
}
}
There is no place in the whole class, that would return an empty JSON object. Something must be here, that I'm doing wrong or what I'm overseeing.
Edit (I don't think this helps)
private function autoprocess($callback)
{
if(is_callable($callback)){
$possibleWFprofiles = WfProfile::where('statusNow', $this->wfRequest->status)->where('conditionalRouting', 1)->get();
if($possibleWFprofiles->count() == 0){
// configuration error....
$result = ["error"=>1, 'message'=>"Unable to find Conditional Routing enabled WfProfiles: ".$this->wfRequest->status];
}
foreach($possibleWFprofiles as $possibleWfProfile){
if(array_search($possibleWfProfile->crFieldname, $this->wfRequestFields)===false){
// fieldname wrongly configured
$result = ["error"=>1, 'message'=>"Unable to find field ".$possibleWfProfile->crFieldname];
}
// see if this is the right one
if($this->wfRequest[$possibleWfProfile->crFieldname] == $possibleWfProfile->crValue){
$this->wfProfile = $possibleWfProfile;
$result = ['error'=>0,'message'=>'Off to loop 2'];
}
}
call_user_func($callback, $result);
}
}
When you make a return $data, inside a anonymous function, it will not be a run's return.
You are not doing nothing with this return in your autoprocess function.
You need to return something in autoprocess and then return in your if:
if($this->wfProfile->autoprocess){
// select new wfProfile and go again.
return $this->autoprocess(function($data){
if($data['error']==0){
$result = null;
return $this->run(); // from here we start over !
}else{
return $data;
}
});
}else{
return ['error'=>0,'message'=>'all good']; // this is where it should go at the end of second loop
}
You need to return your value, for example take this:
function callback($func, $val) {
return call_user_func($func, $val);
}
function run($val) {
if ($val < 10) {
callback(function($val) { return run($val + 1); }, $val);
}
return $val;
}
print(run(0));
this will print empty, but if you do:
function callback($func, $val) {
return call_user_func($func, $val);
}
function run($val) {
if ($val < 10) {
return callback(function($val) { return run($val + 1); }, $val);
}
return $val;
}
print(run(0));
it will print 10
Your function:
public function run()
{
$result = null;
// lets say this is true...
if($this->wfProfile->autoprocess){
// now we are here, where does this return a value???
$this->autoprocess(function($data){
// if it goes here, it never returns a value.
if($data['error']==0){
$result = null;
$this->run(); // from here we start over !
}else{ // if it returns here it still just returns to
// $this->autoprocess, which might return to the
// original run function, but you don't seem to be
// returning its return either...
return $data;
}
});
}else{
return ['error'=>0,'message'=>'all good']; // this is where it should go at the end of second loop
}
}
At the end I chose the imho less elegant way to solve this, so I used goto instead of calling the function again. This is easy to read and to debug/extend in future. So here we go:
public function run()
{
startover:
$result = null;
// more stuff going on here
// Conditional Routing
if($this->wfProfile->autoprocess){
// select new wfProfile and go again.
$result = $this->autoprocess();
if($result['error']==0){
goto startover; // easiest way :-)
}else{
return $result;
}
}else{
return ['error'=>0,'message'=>'all good'];
}
}
and here the autoprocess function
private function autoprocess()
{
$possibleWFprofiles = WfProfile::where('statusNow', $this->wfRequest->status)->where('conditionalRouting', 1)->get();
if($possibleWFprofiles->count() == 0){
// configuration error....
return ["error"=>1, 'message'=>"Unable to find Conditional Routing enabled WfProfiles: ".$this->wfRequest->status];
}
foreach($possibleWFprofiles as $possibleWfProfile){
if(array_search($possibleWfProfile->crFieldname, $this->wfRequestFields)===false){
// fieldname wrongly configured
return ["error"=>1, 'message'=>"Unable to find field ".$possibleWfProfile->crFieldname];
}
// see if this is the right one
if($this->wfRequest[$possibleWfProfile->crFieldname] == $possibleWfProfile->crValue){
$this->wfProfile = $possibleWfProfile;
return ['error'=>0,'message'=>'Off to loop 2'];
}
}
}
I have a lot of functions with parameter that can be either bool or null. If we simplify my functions I have somethings like this:
funtion ($param) {
if ($param) {
//true
} else {
//false
}
}
However, when I call function(null); it obviously goes into else part of condition. So I have to do
funtion ($param) {
if (isset($param)) {
if ($param) {
//true
} else {
//false
}
}
}
for every similar if condition, which is sort of annoying.
So my question is this:
Is there a possibility to do this type of condition with this type of parameter faster and/or without additional function?
To only validate on true and false, use strict type comparison (===):
function check($param)
{
if ($param === true) {
// It's true. :)
} else if ($param === false) {
// It's false.. :o
}
}
This will ignore it if it is null.
Please read the bottom code for the most useful (but least explanative) function.
The below function solves your dilemma. If $param is true or false then the return gives back the boolean version of the $param (useful for such instances as if $param is a sting or an integer etc).
else, nothing is returned by the function which is defined as a NULL value.
example with type clarity texts:
<?php
//Enter your code here, enjoy!
$test[] = NULL;
$test[] = true;
$test[] = false;
$test[] = "string";
$test[] = 45;
function tester($param) {
if(!is_null($param)){
return (boolean)$param?"true":"false";
}
return "null";
}
foreach($test as $row){
print $row . " :: ". tester($row)."\n";
}
Exampled Output:
:: null 1 :: true :: false string :: true 45 ::
true
If you want to return the actual type rather than the textual representation this can be easily achieved with a slimmed down version:
Solution:
function ($param) {
if(!is_null($param)){
return (boolean)$param;
}
// not required but useful to keep for code clarity.
//return null;
}
Possible results:
1 (true) 0 (false) null
I have this simple function:
function isMember($uID, $pdo) {
$status = getUserStatus($uID, $pdo);
if(isAllowed($status['status']))
return $status['status'];
return false;
}
Now I am looking for a way to return false yes, but to return also the value of the variable.
I tried the following, but it makes it empty anyway:
return $status['status'] == false;
So the logi is return false anyway but give me back also the value of the variable, even if it's false, because false should not mean empty :)
Return an array, and use the list() method to get your results:
function isMember($uID, $pdo) {
$status = getUserStatus($uID, $pdo);
$statusString = $status['status'];
$statusFlag = false;
if(isAllowed($status['status']))
$statusFlag = true;
return array($statusFlag,statusString);
}
//usage
list($flag,$msg) = isMember(5,"whatever");
echo "Access: $flag, with message $msg";
A function can not return multiple values, but similar results can be obtained by (1) returning an array or by (2) passing a variable by reference and storing the value you want returned in that variable.
You will need to write your function in a way that it returns an array containing the following:
The value you wan't returned
A flag that signifies true/false
Pass a variable by reference into your function and store the value of the status in that variable.
function isMember($uID, $pdo, &statByRef) {
$status = getUserStatus($uID, $pdo);
if(isAllowed($status['status'])) {
return $status['status'];
}
$statByRef = $status['status'];
return false;
}
False returns empty in PHP, see http://php.net/manual/en/function.empty.php
From documentation:
Determine whether a variable is considered to be empty. A variable is considered empty if it does not exist or if its value equals FALSE. empty() does not generate a warning if the variable does not exist.
Try using something like this:
function isMember($uID, $pdo) {
$status = getUserStatus($uID, $pdo);
if(isAllowed($status['status'])){
return $status['status'];
}
return false;
} // If isAllowed returns true, then PHP will return $Status['Status'];, if not then PHP will by default return false.
I have noticed you haven't used braces which makes the code a little awkward to debug. Then validate like:
if (isMember($Var,$AnotherVar) !== false){
//isMember has not returned false, so PHP is operating within these braces
}
Such a simple thing, which should be most effective.
If your wanting to assign true/false to $status['status']; then you are performing the right method, but wrong operator.
== is a comparision operator. Not assignment
= is an assignment operator, so your assignment should be:
$status['status'] = false;
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 have a function that returns TRUE or FALSE or "Test_operation", and I am looping it to do some things. As you can see the value of $comment_reply is Test_operation.
$comment_reply = $this->Profunction->insert_comments();
echo $comment_reply; // returns Test_operation
if ($comment_reply==TRUE)
{
echo json_encode('Success');
}
elseif($comment_reply==FALSE)
{
echo json_encode('Failed');
}
elseif($comment_reply =="test_operation")
{
echo json_encode('This Action Cannot be done!');
}
But still
if ($comment_reply==TRUE)
{
echo json_encode('Success');
}
This portion getting executed. Why does it happen?
In that function I am returning like this:
return TRUE; // if all success
return FALSE; // if there is some problems
return "Test_operation"; //No insertion need to be done,may be for preview purpose.
SOLVED : I changed bool values to string.
So it will be
return 'TRUE'; // if all success
return 'FALSE'; // if there is some problems
return "Test_operation"; //No insertion need to be done,may be for preview purpose.
Not sure it's your issue, but if you want to enforce equality by type and value, use the === operator.
You can check this out in more detail on the comparison operator page.
Happy coding
Try using === instead of ==