Related
So, I've written some rather convoluted 'functional' PHP code to perform folding on an array. Don't worry, I won't use it anywhere. The problem is, PHP's 'each' function only seems to go as far as the end of an array as it is statically (actually, see bottom) declared.
// declare some arrays to fold with
$six = array("_1_","_2_","_3_","_4_","_5_","_6_");
// note: $ns = range(0,100) won't work at all--lazy evaluation?
$ns = array(1,2,3,4,5,6,7,8);
$ns[8] = 9; // this item is included
// add ten more elements to $ns. each can't find these
for($i=0; $i<10; ++$i)
$ns[] = $i;
// create a copy to see if it fixes 'each' problem
$ms = $ns;
$ms[0] = 3; // Just making sure it's actually a copy
$f = function( $a, $b ) { return $a . $b; };
$pls = function( $a, $b ) { return $a + $b; };
function fold_tr( &$a, $f )
{
$g = function ( $accum, &$a, $f ) use (&$g)
{
list($dummy,$n) = each($a);
if($n)
{
return $g($f($accum,$n),$a,$f);
}
else
{
return $accum;
}
};
reset($a);
return $g( NULL, $a, $f );
}
echo "<p>".fold_tr( $six, $f )."</p>"; // as expected: _1__2__3__4__5__6_
echo "<p>".fold_tr( $ns, $pls )."</p>"; // 45 = sum(1..9)
echo "<p>".fold_tr( $ms, $pls )."</p>"; // 47 = 3 + sum(2..9)
I honestly have no clue how each maintains its state; it seems vestigial at best, since there are better (non-magical) mechanisms in the language for iterating through a list, but does anyone know why it would register items added to an array using $a[$index] = value but not '$a[] = value`? Thanks in advance any insight on this behavior.
Your loop is exiting early thanks to PHP's weak typing:
if($n)
{
return $g($f($accum,$n),$a,$f);
}
else
{
return $accum;
}
when $n is 0 (e.g. $ns[9]), the condition will fail and your loop will terminate. Fix with the following:
if($n !== null)
What would be the fastest, most efficient way to implement a search method that will return an object with a qualifying id?
Sample object array:
$array = [
(object) ['id' => 'one', 'color' => 'white'],
(object) ['id' => 'two', 'color' => 'red'],
(object) ['id' => 'three', 'color' => 'blue']
];
What do I write inside of:
function findObjectById($id){
}
The desired result would return the object at $array[0] if I called:
$obj = findObjectById('one')
Otherwise, it would return false if I passed 'four' as the parameter.
You can iterate that objects:
function findObjectById($id){
$array = array( /* your array of objects */ );
foreach ( $array as $element ) {
if ( $id == $element->id ) {
return $element;
}
}
return false;
}
Edit:
Faster way is to have an array with keys equals to objects' ids (if unique);
Then you can build your function as follow:
function findObjectById($id){
$array = array( /* your array of objects with ids as keys */ );
if ( isset( $array[$id] ) ) {
return $array[$id];
}
return false;
}
It's an old question but for the canonical reference as it was missing in the pure form:
$obj = array_column($array, null, 'id')['one'] ?? false;
The false is per the questions requirement to return false. It represents the non-matching value, e.g. you can make it null for example as an alternative suggestion.
This works transparently since PHP 7.0. In case you (still) have an older version, there are user-space implementations of it that can be used as a drop-in replacement.
However array_column also means to copy a whole array. This might not be wanted.
Instead it could be used to index the array and then map over with array_flip:
$index = array_column($array, 'id');
$map = array_flip($index);
$obj = $array[$map['one'] ?? null] ?? false;
On the index the search problem might still be the same, the map just offers the index in the original array so there is a reference system.
Keep in mind thought that this might not be necessary as PHP has copy-on-write. So there might be less duplication as intentionally thought. So this is to show some options.
Another option is to go through the whole array and unless the object is already found, check for a match. One way to do this is with array_reduce:
$obj = array_reduce($array, static function ($carry, $item) {
return $carry === false && $item->id === 'one' ? $item : $carry;
}, false);
This variant again is with the returning false requirement for no-match.
It is a bit more straight forward with null:
$obj = array_reduce($array, static function ($carry, $item) {
return $carry ?? ($item->id === 'one' ? $item : $carry);
}, null);
And a different no-match requirement can then be added with $obj = ...) ?? false; for example.
Fully exposing to foreach within a function of its own even has the benefit to directly exit on match:
$result = null;
foreach ($array as $object) {
if ($object->id === 'one') {
$result = $object;
break;
}
}
unset($object);
$obj = $result ?? false;
This is effectively the original answer by hsz, which shows how universally it can be applied.
You can use the function array_search of php like this
$key=array_search("one", array_column(json_decode(json_encode($array),TRUE), 'color'));
var_dump($array[$key]);
i: is the index of item in array
1: is the property value looking for
$arr: Array looking inside
'ID': the property key
$i = array_search(1, array_column($arr, 'ID'));
$element = ($i !== false ? $arr[$i] : null);
Well, you would would have to loop through them and check compare the ID's unless your array is sorted (by ID) in which case you can implement a searching algorithm like binary search or something of that sort to make it quicker.
My suggestion would be to first sort the arrays using a sorting algorithm (binary sort, insertion sort or quick sort) if the array is not sorted already. Then you can implement a search algorithm which should improve performance and I think that's as good as it gets.
http://www.algolist.net/Algorithms/Binary_search
This is my absolute favorite algorithm for very quickly finding what I need in a very large array, quickly. It is a Binary Search Algorithm implementation I created and use extensively in my PHP code. It hands-down beats straight-forward iterative search routines. You can vary it a multitude of ways to fit your need, but the basic algorithm remains the same.
To use it (this variation), the array must be sorted, by the index you want to find, in lowest-to-highest order.
function quick_find(&$array, $property, $value_to_find, &$first_index) {
$l = 0;
$r = count($array) - 1;
$m = 0;
while ($l <= $r) {
$m = floor(($l + $r) / 2);
if ($array[$m]->{$property} < $value_to_find) {
$l = $m + 1;
} else if ($array[$m]->{$property} > $value_to_find) {
$r = $m - 1;
} else {
$first_index = $m;
return $array[$m];
}
}
return FALSE;
}
And to test it out:
/* Define a class to put into our array of objects */
class test_object {
public $index;
public $whatever_you_want;
public function __construct( $index_to_assign ) {
$this->index = $index_to_assign;
$this->whatever_you_want = rand(1, 10000000);
}
}
/* Initialize an empty array we will fill with our objects */
$my_array = array();
/* Get a random starting index to simulate data (possibly loaded from a database) */
$my_index = rand(1256, 30000);
/* Say we are needing to locate the record with this index */
$index_to_locate = $my_index + rand(200, 30234);
/*
* Fill "$my_array()" with ONE MILLION objects of type "test_object"
*
* 1,000,000 objects may take a little bit to generate. If you don't
* feel patient, you may lower the number!
*
*/
for ($i = 0; $i < 1000000; $i++) {
$searchable_object = new test_object($my_index); // Create the object
array_push($my_array, $searchable_object); // Add it to the "$my_array" array
$my_index++; /* Increment our unique index */
}
echo "Searching array of ".count($my_array)." objects for index: " . $index_to_locate ."\n\n";
$index_found = -1; // Variable into which the array-index at which our object was found will be placed upon return of the function.
$object = quick_find($my_array, "index", $index_to_locate, $index_found);
if ($object == NULL) {
echo "Index $index_to_locate was not contained in the array.\n";
} else {
echo "Object found at index $index_found!\n";
print_r($object);
}
echo "\n\n";
Now, a few notes:
You MAY use this to find non-unique indexes; the array MUST still be sorted in ascending order. Then, when it finds an element matching your criteria, you must walk the array backwards to find the first element, or forward to find the last. It will add a few "hops" to your search, but it will still most likely be faster than iterating a large array.
For STRING indexes, you can change the arithmetic comparisons (i.e. " > " and " < " ) in quick_find() to PHP's function "strcasecmp()". Just make sure the STRING indexes are sorted the same way (for the example implementation): Alphabetically and Ascending.
And if you want to have a version that can search arrays of objects sorted in EITHER ascending OR decending order:
function quick_find_a(&$array, $property, $value_to_find, &$first_index) {
$l = 0;
$r = count($array) - 1;
$m = 0;
while ($l <= $r) {
$m = floor(($l + $r) / 2);
if ($array[$m]->{$property} < $value_to_find) {
$l = $m + 1;
} else if ($array[$m]->{$property} > $value_to_find) {
$r = $m - 1;
} else {
$first_index = $m;
return $array[$m];
}
}
return FALSE;
}
function quick_find_d(&$array, $property, $value_to_find, &$first_index) {
$l = 0;
$r = count($array) - 1;
$m = 0;
while ($l <= $r) {
$m = floor(($l + $r) / 2);
if ($value_to_find > $array[$m]->{$property}) {
$r = $m - 1;
} else if ($value_to_find < $array[$m]->{$property}) {
$l = $m + 1;
} else {
$first_index = $m;
return $array[$m];
}
}
return FALSE;
}
function quick_find(&$array, $property, $value_to_find, &$first_index) {
if ($array[0]->{$property} < $array[count($array)-1]->{$property}) {
return quick_find_a($array, $property, $value_to_find, $first_index);
} else {
return quick_find_d($array, $property, $value_to_find, $first_index);
}
}
The thing with performance of data structures is not only how to get but mostly how to store my data.
If you are free to design your array, use an associative array:
$array['one']->id = 'one';
$array['one']->color = 'white';
$array['two']->id = 'two';
$array['two']->color = 'red';
$array['three']->id = 'three';
$array['three']->color = 'blue';
Finding is then the most cheap: $one = $array['one];
UPDATE:
If you cannot modify your array constitution, you could create a separate array which maps ids to indexes. Finding an object this way does not cost any time:
$map['one'] = 0;
$map['two'] = 1;
$map['three'] = 2;
...
getObjectById() then first lookups the index of the id within the original array and secondly returns the right object:
$index = $map[$id];
return $array[$index];
Something I like to do in these situations is to create a referential array, thus avoiding having to re-copy the object but having the power to use the reference to it like the object itself.
$array['one']->id = 'one';
$array['one']->color = 'white';
$array['two']->id = 'two';
$array['two']->color = 'red';
$array['three']->id = 'three';
$array['three']->color = 'blue';
Then we can create a simple referential array:
$ref = array();
foreach ( $array as $row )
$ref[$row->id] = &$array[$row->id];
Now we can simply test if an instance exists in the array and even use it like the original object if we wanted:
if ( isset( $ref['one'] ) )
echo $ref['one']->color;
would output:
white
If the id in question did not exist, the isset() would return false, so there's no need to iterate the original object over and over looking for a value...we just use PHP's isset() function and avoid using a separate function altogether.
Please note when using references that you want use the "&" with the original array and not the iterator, so using &$row would not give you what you want.
This is definitely not efficient, O(N). But it looks sexy:
$result = array_reduce($array, function ($found, $obj) use ($id) {
return $obj['id'] == $id ? $obj : $found;
}, null);
addendum:
I see hakre already posted something akin to this.
Here is what I use. Reusable functions that loop through an array of objects. The second one allows you to retrieve a single object directly out of all matches (the first one to match criteria).
function get_objects_where($match, $objects) {
if ($match == '' || !is_array($match)) return array ();
$wanted_objects = array ();
foreach ($objects as $object) {
$wanted = false;
foreach ($match as $k => $v) {
if (is_object($object) && isset($object->$k) && $object->$k == $v) {
$wanted = true;
} else {
$wanted = false;
break;
};
};
if ($wanted) $wanted_objects[] = $object;
};
return $wanted_objects;
};
function get_object_where($match, $objects) {
if ($match == '' || !is_array($match)) return (object) array ();
$wanted_objects = get_objects_where($match, $objects);
return count($wanted_objects) > 0 ? $wanted_objects[0] : (object) array ();
};
The easiest way:
function objectToArray($obj) {
return json_decode(json_encode($obj), true);
}
This is probably a simple question...
I have a multidimensional array called $form. I need to iterate through the array, looking for specific keys that match another array values and then perform an action in those keys.
$a = 'theme_select';
$b = 'timezone';
$c = 'contact';
$d = 'something_else';
$arr = array();
$arr = ($a, $b, $c, $d);
foreach($form as $form_key=>$form_val){
foreach($arr as $include) {
if ($form_key == $include) {
//some action
}
}
}
Is this the best way to accomplish this? The reason I'm asking is that $form can be quite big and I fear that page loading can become quite slow.
Have a look at the array_intersect_key() function
$a = 'theme_select';
$b = 'timezone';
$c = 'contact';
$d = 'something_else';
$arr = array_fill_keys(array($a, $b, $c, $d),1);
$matchingKeys = array_intersect_keys($form,$arr);
foreach($matchingKeys as $key => $value) {
...
}
I need to return multiple values from a function, therefore I have added them to an array and returned the array.
<?
function data(){
$a = "abc";
$b = "def";
$c = "ghi";
return array($a, $b, $c);
}
?>
How can I receive the values of $a, $b, $c by calling the above function?
You can add array keys to your return values and then use these keys to print the array values, as shown here:
function data() {
$out['a'] = "abc";
$out['b'] = "def";
$out['c'] = "ghi";
return $out;
}
$data = data();
echo $data['a'];
echo $data['b'];
echo $data['c'];
you can do this:
list($a, $b, $c) = data();
print "$a $b $c"; // "abc def ghi"
function give_array(){
$a = "abc";
$b = "def";
$c = "ghi";
return compact('a','b','c');
}
$my_array = give_array();
http://php.net/manual/en/function.compact.php
The data function is returning an array, so you can access the result of the function in the same way as you would normally access elements of an array:
<?php
...
$result = data();
$a = $result[0];
$b = $result[1];
$c = $result[2];
Or you could use the list() function, as #fredrik recommends, to do the same thing in a line.
<?php
function demo($val,$val1){
return $arr=array("value"=>$val,"value1"=>$val1);
}
$arr_rec=demo(25,30);
echo $arr_rec["value"];
echo $arr_rec["value1"];
?>
$array = data();
print_r($array);
From PHP 5.4 you can take advantage of array dereferencing and do something like this:
<?
function data()
{
$retr_arr["a"] = "abc";
$retr_arr["b"] = "def";
$retr_arr["c"] = "ghi";
return $retr_arr;
}
$a = data()["a"]; //$a = "abc"
$b = data()["b"]; //$b = "def"
$c = data()["c"]; //$c = "ghi"
?>
Maybe this is what you searched for :
function data() {
// your code
return $array;
}
$var = data();
foreach($var as $value) {
echo $value;
}
In order to get the values of each variable, you need to treat the function as you would an array:
function data() {
$a = "abc";
$b = "def";
$c = "ghi";
return array($a, $b, $c);
}
// Assign a variable to the array;
// I selected $dataArray (could be any name).
$dataArray = data();
list($a, $b, $c) = $dataArray;
echo $a . " ". $b . " " . $c;
//if you just need 1 variable out of 3;
list(, $b, ) = $dataArray;
echo $b;
//Important not to forget the commas in the list(, $b,).
here is the best way in a similar function
function cart_stats($cart_id){
$sql = "select sum(price) sum_bids, count(*) total_bids from carts_bids where cart_id = '$cart_id'";
$rs = mysql_query($sql);
$row = mysql_fetch_object($rs);
$total_bids = $row->total_bids;
$sum_bids = $row->sum_bids;
$avarage = $sum_bids/$total_bids;
$array["total_bids"] = "$total_bids";
$array["avarage"] = " $avarage";
return $array;
}
and you get the array data like this
$data = cart_stats($_GET['id']);
<?=$data['total_bids']?>
All of the above seems to be outdated since PHP 7.1., as #leninzprahy mentioned in a comment.
If you are looking for a simple way to access values returned in an array like you would in python, this is the syntax to use:
[$a, $b, $c] = data();
I think the best way to do it is to create a global var array. Then do whatever you want to it inside the function data by passing it as a reference. No need to return anything too.
$array = array("white", "black", "yellow");
echo $array[0]; //this echo white
data($array);
function data(&$passArray){ //<<notice &
$passArray[0] = "orange";
}
echo $array[0]; //this now echo orange
This is what I did inside the yii framewok:
public function servicesQuery($section){
$data = Yii::app()->db->createCommand()
->select('*')
->from('services')
->where("section='$section'")
->queryAll();
return $data;
}
then inside my view file:
<?php $consultation = $this->servicesQuery("consultation"); ?> ?>
<?php foreach($consultation as $consul): ?>
<span class="text-1"><?php echo $consul['content']; ?></span>
<?php endforeach;?>
What I am doing grabbing a cretin part of the table i have selected. should work for just php minus the "Yii" way for the db
The underlying problem revolves around accessing the data within the array, as Felix Kling points out in the first response.
In the following code, I've accessed the values of the array with the print and echo constructs.
function data()
{
$a = "abc";
$b = "def";
$c = "ghi";
$array = array($a, $b, $c);
print_r($array);//outputs the key/value pair
echo "<br>";
echo $array[0].$array[1].$array[2];//outputs a concatenation of the values
}
data();
I was looking for an easier method than i'm using but it isn't answered in this post. However, my method works and i don't use any of the aforementioned methods:
function MyFunction() {
$lookyHere = array(
'value1' => array('valuehere'),
'entry2' => array('valuehere')
);
return $lookyHere;
}
I have no problems with my function. I read the data in a loop to display my associated data. I have no idea why anyone would suggest the above methods. If you are looking to store multiple arrays in one file but not have all of them loaded, then use my function method above. Otherwise, all of the arrays will load on the page, thus, slowing down your site. I came up with this code to store all of my arrays in one file and use individual arrays when needed.
Your function is:
function data(){
$a = "abc";
$b = "def";
$c = "ghi";
return array($a, $b, $c);
}
It returns an array where position 0 is $a, position 1 is $b and position 2 is $c. You can therefore access $a by doing just this:
data()[0]
If you do $myvar = data()[0] and print $myvar, you will get "abc", which was the value assigned to $a inside the function.
Is it possible to have a function with two returns like this:
function test($testvar)
{
// Do something
return $var1;
return $var2;
}
If so, how would I be able to get each return separately?
Technically, you can't return more than one value. However, there are multiple ways to work around that limitation. The way that acts most like returning multiple values, is with the list keyword:
function getXYZ()
{
return array(4,5,6);
}
list($x,$y,$z) = getXYZ();
// Afterwards: $x == 4 && $y == 5 && $z == 6
// (This will hold for all samples unless otherwise noted)
Technically, you're returning an array and using list to store the elements of that array in different values instead of storing the actual array. Using this technique will make it feel most like returning multiple values.
The list solution is a rather php-specific one. There are a few languages with similar structures, but more languages that don't. There's another way that's commonly used to "return" multiple values and it's available in just about every language (in one way or another). However, this method will look quite different so may need some getting used to.
// note that I named the arguments $a, $b and $c to show that
// they don't need to be named $x, $y and $z
function getXYZ(&$a, &$b, &$c)
{
$a = 4;
$b = 5;
$c = 6;
}
getXYZ($x, $y, $z);
This technique is also used in some functions defined by php itself (e.g. $count in str_replace, $matches in preg_match). This might feel quite different from returning multiple values, but it is worth at least knowing about.
A third method is to use an object to hold the different values you need. This is more typing, so it's not used quite as often as the two methods above. It may make sense to use this, though, when using the same set of variables in a number of places (or of course, working in a language that doesn't support the above methods or allows you to do this without extra typing).
class MyXYZ
{
public $x;
public $y;
public $z;
}
function getXYZ()
{
$out = new MyXYZ();
$out->x = 4;
$out->y = 5;
$out->z = 6;
return $out;
}
$xyz = getXYZ();
$x = $xyz->x;
$y = $xyz->y;
$z = $xyz->z;
The above methods sum up the main ways of returning multiple values from a function. However, there are variations on these methods. The most interesting variations to look at, are those in which you are actually returning an array, simply because there's so much you can do with arrays in PHP.
First, we can simply return an array and not treat it as anything but an array:
function getXYZ()
{
return array(1,2,3);
}
$array = getXYZ();
$x = $array[0];
$y = $array[1];
$z = $array[2];
The most interesting part about the code above is that the code inside the function is the same as in the very first example I provided; only the code calling the function changed. This means that it's up to the one calling the function how to treat the result the function returns.
Alternatively, one could use an associative array:
function getXYZ()
{
return array('x' => 4,
'y' => 5,
'z' => 6);
}
$array = getXYZ();
$x = $array['x'];
$y = $array['y'];
$z = $array['z'];
Php does have the compact function that allows you to do same as above but while writing less code. (Well, the sample won't have less code, but a real world application probably would.) However, I think the amount of typing saving is minimal and it makes the code harder to read, so I wouldn't do it myself. Nevertheless, here's a sample:
function getXYZ()
{
$x = 4;
$y = 5;
$z = 6;
return compact('x', 'y', 'z');
}
$array = getXYZ();
$x = $array['x'];
$y = $array['y'];
$z = $array['z'];
It should be noted that while compact does have a counterpart in extract that could be used in the calling code here, but since it's a bad idea to use it (especially for something as simple as this) I won't even give a sample for it. The problem is that it will do "magic" and create variables for you, while you can't see which variables are created without going to other parts of the code.
Finally, I would like to mention that list doesn't really play well with associative array. The following will do what you expect:
function getXYZ()
{
return array('x' => 4,
'y' => 5,
'z' => 6);
}
$array = getXYZ();
list($x, $y, $z) = getXYZ();
However, the following will do something different:
function getXYZ()
{
return array('x' => 4,
'z' => 6,
'y' => 5);
}
$array = getXYZ();
list($x, $y, $z) = getXYZ();
// Pay attention: $y == 6 && $z == 5
If you used list with an associative array, and someone else has to change the code in the called function in the future (which may happen just about any situation) it may suddenly break, so I would recommend against combining list with associative arrays.
There is no way of returning 2 variables. Although, you can propagate an array and return it; create a conditional to return a dynamic variable, etc.
For instance, this function would return $var2
function wtf($blahblah = true) {
$var1 = "ONe";
$var2 = "tWo";
if($blahblah === true) {
return $var2;
}
return $var1;
}
In application:
echo wtf();
//would echo: tWo
echo wtf("not true, this is false");
//would echo: ONe
If you wanted them both, you could modify the function a bit
function wtf($blahblah = true) {
$var1 = "ONe";
$var2 = "tWo";
if($blahblah === true) {
return $var2;
}
if($blahblah == "both") {
return array($var1, $var2);
}
return $var1;
}
echo wtf("both")[0]
//would echo: ONe
echo wtf("both")[1]
//would echo: tWo
list($first, $second) = wtf("both")
// value of $first would be $var1, value of $second would be $var2
In your example, the second return will never happen - the first return is the last thing PHP will run. If you need to return multiple values, return an array:
function test($testvar) {
return array($var1, $var2);
}
$result = test($testvar);
echo $result[0]; // $var1
echo $result[1]; // $var2
Since PHP 7.1 we have proper destructuring for lists.
Thereby you can do things like this:
$test = [1, 2, 3, 4];
[$a, $b, $c, $d] = $test;
echo($a);
> 1
echo($d);
> 4
In a function this would look like this:
function multiple_return() {
return ['this', 'is', 'a', 'test'];
}
[$first, $second, $third, $fourth] = multiple_return();
echo($first);
> this
echo($fourth);
> test
Destructuring is a very powerful tool. It's capable of destructuring key=>value pairs as well:
["a" => $a, "b" => $b, "c" => $c] = ["a" => 1, "b" => 2, "c" => 3];
Take a look at the new feature page for PHP 7.1:
New features
In PHP 5.5 there is also a new concept: generators, where you can yield multiple values from a function:
function hasMultipleValues() {
yield "value1";
yield "value2";
}
$values = hasMultipleValues();
foreach ($values as $val) {
// $val will first be "value1" then "value2"
}
Or you can pass by reference:
function byRef($x, &$a, &$b)
{
$a = 10 * $x;
$b = 100 * $x;
}
$a = 0;
$b = 0;
byRef(10, $a, $b);
echo $a . "\n";
echo $b;
This would output
100
1000
For PHP 7.1.0 onwards, you can use the new syntax (instead of the list function):
/**
* #return array [foo, bar]
*/
function getFooAndBar(): array {
return ['foo', 'bar'];
}
[$foo, $bar] = getFooAndBar();
print 'Hello '. $foo . ' and ' . $bar;
It's OK for me if you want to return 2-3 variables, otherwise you should use an object with the desired properties.
I know that I am pretty late, but there is a nice and simple solution for this problem.
It's possible to return multiple values at once using destructuring.
function test()
{
return [ 'model' => 'someValue' , 'data' => 'someothervalue'];
}
Now you can use this
$result = test();
extract($result);
extract creates a variable for each member in the array, named after that member. You can therefore now access $model and $data
You can return multiple arrays and scalars from a function
function x()
{
$a=array("a","b","c");
$b=array("e","f");
return array('x',$a,$b);
}
list ($m,$n,$o)=x();
echo $m."\n";
print_r($n);
print_r($o);
Its not possible have two return statement. However it doesn't throw error but when function is called you will receive only first return statement value.
We can use return of array to get multiple values in return. For Example:
function test($testvar)
{
// do something
//just assigning a string for example, we can assign any operation result
$var1 = "result1";
$var2 = "result2";
return array('value1' => $var1, 'value2' => $var2);
}
Best Practice is to put your returned variables into array and then use list() to assign array values to variables.
<?php
function add_subt($val1, $val2) {
$add = $val1 + $val2;
$subt = $val1 - $val2;
return array($add, $subt);
}
list($add_result, $subt_result) = add_subt(20, 7);
echo "Add: " . $add_result . '<br />';
echo "Subtract: " . $subt_result . '<br />';
?>
Functions, by definition, only return one value.
However, as you assumed, that value can be an array.
So you can certainly do something like:
<?PHP
function myfunc($a,$b){
return array('foo'=>$a,'bar'=>$b);
}
print_r(myfunc('baz','bork'));
That said, it's worth taking a moment and thinking about whatever you're trying to solve. While returning a complex result value (like an array, or an object) is perfectly valid, if you're thinking is that "I want to return two values", you might be designing poorly. Without more detail in your question, it's hard to say, but it never hurts to stop and think twice.
The answer that's given the green tick above is actually incorrect. You can return multiple values in PHP, if you return an array. See the following code for an example:
<?php
function small_numbers()
{
return array (0, 1, 2);
}
list ($zero, $one, $two) = small_numbers();
This code is actually copied from the following page on PHP's website: http://php.net/manual/en/functions.returning-values.php
I've also used the same sort of code many times myself, so can confirm that it's good and that it works.
Yes, you can use an object :-)
But the simplest way is to return an array:
return array('value1', 'value2', 'value3', '...');
I have implement like this for multiple return value PHP function. be nice with your code. thank you.
<?php
function multi_retun($aa)
{
return array(1,3,$aa);
}
list($one,$two,$three)=multi_retun(55);
echo $one;
echo $two;
echo $three;
?>
PHP 7.1 Update
Return an array.
function test($testvar)
{
// Do something
return [$var1, $var2];
}
then use that like below:
[$value1, $value2] = test($testvar);
Functions in PHP can return only one variable. you could use variables with global scope, you can return array, or you can pass variable by reference to the function and than change value,.. but all of that will decrease readability of your code.
I would suggest that you look into the classes.
Thought I would expand on a few of the responses from above....
class nameCheck{
public $name;
public function __construct(){
$this->name = $name;
}
function firstName(){
// If a name has been entered..
if(!empty($this->name)){
$name = $this->name;
$errflag = false;
// Return a array with both the name and errflag
return array($name, $errflag);
// If its empty..
}else if(empty($this->name)){
$errmsg = 'Please enter a name.';
$errflag = true;
// Return both the Error message and Flag
return array($errmsg, $errflag);
}
}
}
if($_POST['submit']){
$a = new nameCheck;
$a->name = $_POST['name'];
// Assign a list of variables from the firstName function
list($name, $err) = $a->firstName();
// Display the values..
echo 'Name: ' . $name;
echo 'Errflag: ' . $err;
}
?>
<form method="post" action="<?php $_SERVER['PHP_SELF']; ?>" >
<input name="name" />
<input type="submit" name="submit" value="submit" />
</form>
This will give you a input field and a submit button once submitted, if the name input field is empty it will return the error flag and a message. If the name field has a value it will return the value/name and a error flag of 0 for false = no errors.
Hope this helps!
Some might prefer returning multiple values as object:
function test() {
$object = new stdClass();
$object->x = 'value 1';
$object->y = 'value 2';
return $object;
}
And call it like this:
echo test()->x;
Or:
$test = test();
echo $test->y;
Yes and no. You can't return more than one variable / object, but as you suggest, you can put them into an array and return that.
There is no limit to the nesting of arrays, so you can just package them up that way to return.
You can always only return one variable which might be an array. But You can change global variables from inside the function. That is most of the time not very good style, but it works. In classes you usually change class varbiables from within functions without returning them.
The answer is no. When the parser reaches the first return statement, it will direct control back to the calling function - your second return statement will never be executed.
Add all variables in an array and then finally return the array.
function test($testvar)
{
// do something
return array("var1" => $var1, "var2" => #var2);
}
And then
$myTest = test($myTestVar);
//$myTest["var1"] and $myTest["var2"] will be usable
I think eliego has explained the answer clearly. But if you want to return both values, put them into a array and return it.
function test($testvar)
{
// do something
return array('var1'=>$var1,'var2'=>$var2);
//defining a key would be better some times
}
//to access return values
$returned_values = test($testvar);
echo $returned_values['var1'];
echo $returned_values['var2'];
<?php
function foo(){
$you = 5;
$me = 10;
return $you;
return $me;
}
echo foo();
//output is just 5 alone so we cant get second one it only retuns first one so better go with array
function goo(){
$you = 5;
$me = 10;
return $you_and_me = array($you,$me);
}
var_dump(goo()); // var_dump result is array(2) { [0]=> int(5) [1]=> int(10) } i think thats fine enough
?>
Languages which allow multiple returns usually just convert the multiple values into a data structure.
For example, in Python you can return multiple values. However, they're actually just being returned as one tuple.
So you can return multiple values in PHP by just creating a simple array and returning that.
You can get the values of two or more variables by setting them by reference:
function t(&$a, &$b) {
$a = 1;
$b = 2;
}
t($a, $b);
echo $a . ' ' . $b;
Output:
1 2
Does PHP still use "out parameters"? If so, you can use the syntax to modify one or more of the parameters going in to your function then. You would then be free to use the modified variable after your function returns.
$var1 = 0;
$var2 = 0;
function test($testvar, &$var1 , &$var2)
{
$var1 = 1;
$var2 = 2;
return;
}
test("", $var1, $var2);
// var1 = 1, var2 = 2
It's not a good way, but I think we can set two variables in a function at the same time.
This is the easiest way to do it:
public function selectAllUsersByRole($userRole, $selector) {
$this->userRole = $userLevel;
$this->selector = $selector;
$sql = "SELECT * FROM users WHERE role <= ? AND del_stat = 0";
$stm = $this->connect()->prepare($sql); // Connect function in Dbh connect to database file
$stm->execute([$this->userRole]); // This is PHP 7. Use array($this->userRole) for PHP 5
$usersIdArray = array();
$usersFNameArray = array();
$usersLNameArray = array();
if($stm->rowCount()) {
while($row = $stm->fetch()) {
array_push($usersIdArray, $row['id']);
array_push($usersFNameArray, $row['f_name']);
array_push($usersLNameArray, $row['l_name']);
// You can return only $row['id'] or f_name or ...
// I used the array because it's most used.
}
}
if($this->selector == 1) {
return $usersIdArray;
}elseif($this->selector == 2) {
return $usersFNameArray;
}elseif($this->selector == 3) {
return $usersLNameArray;
}
}
How can we call this function?
$idData = $selectAllUsers->selectAllUsersByLevel($userRole, 0);
print_r($idData);
$idFName = $selectAllUsers->selectAllUsersByLevel($userRole, 1);
print_r($idFname);
That's it. Very easy.