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)
Let's say I have a function like this:
function z($zzz){
for($c=0;$c<5;$c++){
$zzz[$c]= 10;
//more and more codes
}
}
I want to write a loop so that
the 1st time the function is executed, argument $array is passed
the 2nd time : argument $array[0] is passed
while the 3rd time : argument $array[1] is passed
.....
and the 12th time : argument $array[0][0] is passed
This is what comes to my mind:
$a = -1;
$b = -1;
$array = array();
while($a<10){
while($b<10){
z($array);
$b++;
$array= &$array[$b];
}
$a++;
$array= &$array[$a];
}
I've tried it but it didn't work..
I would appreciate if someone can provide a solution..
If z() is supposed to change the passed array, your function definition should be:
function z(&$zzz)
$a = 0;
while ($a < 99) // <-- edit as applicable
{
$b = 0
while ($b < 12)
{
if ($b == 0)
{
Z($array[$a]);
} else
{
Z($array[$a][$b]);
}
$b++;
}
$a++;
}
And as stated by Jack you need to pass the $array variable by reference for update. Not too sure what that function is trying to achieve though. If you need to fill an array with a predermined dimension, maybe array_fill could be more useful.
http://www.php.net/manual/en/function.array-fill.php
function z(&$zzz){
for($c=0;$c<5;$c++){
$zzz[$c]= 10;
//more and more codes
}
}
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.
Now, before you jump at how you shouldn't mix scopes: I realize this. However, this is a case where either scope mixing must occur or major code duplication must occur—nothing around it. And I'd prefer scope mixing.
That said, I'd like this code:
function a() {
$a = "a";
$b = "b";
$c = "c";
}
function b() {
a();
echo $a . $b . $c;
}
b(); // Output: abc
echo $a; // Should raise a notice that $a is undefined
to be able to work as commented. I know it's not possible in most languages—I was able to do it in Ruby, though; and wonder if you can do it with PHP.
The names of variables aren't known beforehand in the real situation.
Again, it's code duplication or this—absolutely no way around it.
Also, it'd be okay if a had to be something like a('b') or something.
In reality, the code is this:
static function renderError($what, $vararray) {
foreach($vararray as $key => $val) { /* this foreach is the code we want to decouple */
$key = 'e_'.$key;
$$key = htmlspecialchars($val);
}
ob_clean();
exit(eval('?>'.file_get_contents(ROOT."/templates/$what.php")));
}
With a call like E_Render::renderError('NotFound', array( 'requested_url' => '/notfound', 'misspelling' => '/reallynotfound' ));
Then, in templates/NotFound.php, you'd have something like:
<html>
<body>
<?php echo $e_requested_url; ?> could not be found. Did you mean <?php echo $e_misspelling: ?>?
</body>
</html>
We'd really rather not have our template authors do anything more than that...although $e['requested_url'] could be done if nothing better was available.
That's why we have OO:
class Foo {
function a() {
$this->a = "a";
$this->b = "b";
$this->c = "c";
}
function b() {
$this->a();
echo $this->a . $this->b . $this->c;
}
}
$f = new Foo;
$f->b(); // Output: abc
echo $a; // Should raise a notice that $a is undefined
Alternatively:
function a() {
$a = "a";
$b = "b";
$c = "c";
return compact('a', 'b', 'c');
}
function b() {
extract(a());
echo $a . $b . $c;
}
See: compact(), extract()
Otherwise I don't see a way of doing this without drastically changing the language.
PS: If you feel this feature is so important, why don't you just use Ruby?
There's no way to do what you're asking given the restrictions you are imposing. There's never going to be a good reason to do exactly what you are trying to do. There's plenty of better solutions.
Anyway, the closest you'll get is passing by reference:
<?php
function a(&$a, &$b, &$c)
{
$a = 1;
$b = 2;
$c = 3;
}
function b()
{
a($a, $b, $c);
}
?>
I just ran this code
-- var1.php
<?php
function a($vars) {
foreach ($vars as $var => $val) {
$$var = $val;
}
echo eval('?>' . file_get_contents('var2.php') . '<?php ');
};
a(array('a' => 'foo', 'b' => 'bar', 'c' => 'baz'));
-- var2.php
<html>
<body>
<div><?= '$a = "' . $a . '"' ?></div>
<div><?= '$b = "' . $b . '"' ?></div>
<div><?= '$c = "' . $c . '"' ?></div>
</body>
</html>
And it outputs :
$a = "foo"
$b = "bar"
$c = "baz"
The reason being that since eval() keeps the current scope, any variable declared locally inside the function will also be available locally inside the eval'ed string. Same thing with $this.
** UPDATE **
Since eval() is evil and should be avoided (as kindly suggested), here's a rewrite using simple templating. This way, your designer only has to know the variable name available (in the specs) :
-- var1.php
<?php
function showError($error, $vars) {
$template = file_get_contents("{$error}.php");
$keys = array();
$values = array();
foreach ($vars as $var => $val) {
$keys[] = '#{e_'.$var.'}';
$values[] = $val;
}
echo str_replace($keys, $values, $template);
};
showError('template1', array('value' => 300, 'message' => 'Something foo'));
-- template1.php
<html>
<body>
<div>Error <span style="font-weight: bold; color: red;">#{e_value}</span></div>
<div>The message was : <em>#{e_message}</em></div>
</body>
</html>
why can't you return $a from a()?
function a() {
$a = "a";
return $a;
}
function b() {
$a = a();
echo $a;
}
b(); // Output: a
echo $a; // Should raise a notice that $a is undefined
this does not break scope.
I do not understand why you cannot return them as an array. Besides the suggestion #NullUserException gave you, I would suggest the following approach (if you do not take the OOP route).
function a() {
$a = "a";
$b = "b";
$c = "c";
return array($a, $b, $c);
}
function b() {
list($a, $b, $c) = a();
echo $a . $b . $c;
}
I need to parse a number that has 3 s.f. and 2 d.p. (e.g. 2.34). The first two numbers (1st and 2nd s.f.) are then multiplied by 10. The second number stays as it is. Thus, for the example above, $a = 23 and $b = 4. I was able to get code similar to below to work when it was not a function but I would like to be able to incorporate the code into a function. I would like to be able to get the value $a and the value $b out of the function (separately if possible) but I am having problems doing this. Any help would be much appreciated.
$z = 1.63;
function getcoordinates($conv) {
$z = number_format($conv, 2);
$z = (string)$z;
$a = substr($z,0,3)*10;
$b = substr($z,3,1);
$a = settype($a, "float");
$b = settype($b, "float");
return $a;
return $b;
}
Why can’t you just calculate the values the way you described?
function getCoordinates($input) {
$a = floor($input * 10) % 100;
$b = floor($input * 100) % 10;
return array($a, $b);
}
As demonstrated here, you can use array() to return multiple values. When you call the function, you can use list() to put the values into separate variables:
list($a, $b) = getCoordinates(2.34);
echo "$a, $b\n"; // prints “23, 4”
Return an array.
return array($a, $b);
and, on the call site, receive the value with
list($a, $b) = getcoordinates(...);
function getcoordinates($conv) {
/* your code */
return array($a,$b);
}