Forum Moderators: coopster

Message Too Old, No Replies

explanation of arrays and "pointers"

php arrays

         

highseas

2:24 pm on May 27, 2011 (gmt 0)

10+ Year Member



Hello all,

I am new to php and am working on building a model and this is one of the functions that is using an array as input. Can someone overall explain what is going on here, with how the pointer work and all that?

Thanks for any quick tips.


<?= dropdown_field(

array('label' => 'Project',
'name' => 'oa_item[project_id]',
'id' => 'project_id',
'class' => 'size-medium',
'options' => $projectOptions,
'selection' => $oa->project_id)

)
?>

rocknbil

5:05 pm on May 27, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



First, short codes are deprecated:

<?

use this instead.

<?php

This is not the function itself, this is a call to the function dropdown_field, which I presume accepts an associative array as a parameter. It also tells me the function echoes from within itself, which is kind of bad programming. A function should return a value in case you want to do other things with it.

To understand that, here's a little sample which passes a flat scalar value as a parameter. A scalar is a string, a flat value without dimension, an array is a list.

$test = 'Hello';

echo function_test($test);

function function_test($the_string) {
$mystring = $this_string . " world";
return $mystring;
}

We pass the value of $test to function_test as a parameter, on which we operate by adding " world" to it and return the value. An important thing here when we get to your array - within the function, "$test" now turns into "$the_string." $the_string is a localized variable, meaning it's value is only relevant in the scope of the function. Any values outside of this function that you set to a variable "$the_string" will not affect the variable value in the function (unless you declare it as a global, which you shouldn't.) This is part of the power of functions, they operate as black boxes - pass it parameters, it operates on them, returns a value.


The previous will echo out "Hello world" to the browser. Because it returns a value, we can do the same thing like so.

$test = 'Hello';
$my_new_variable = function_test($test) . ", I totally rock!"
echo $my_new_variable;

This will echo "Hello world, I totally rock!" to the browser. But this only works because we don't echo directly in the function. We take it's returned value then concatenate (add to) another string to it before actually using it. If my function did this,

function function_test($the_string) {
$mystring = $this_string . " world";
echo $mystring;
}

we've robbed it of a potential functionality of a return value.

(Actually the previous **would** work only because of the order in which we execute it - but hopefully the point is made that by making a function echo, that's all it can ever do. We want to be able to repurpose our functions so we can do other things with their returned values.)

So your original call to the function uses an array instead of a scalar. The below is a synonymous call to the function - and probably better, because you can store the array in a configuration file instead of hard coded in the PHP:

$mylist = array(
'label' => 'Project',
'name' => 'oa_item[project_id]',
'id' => 'project_id',
'class' => 'size-medium',
'options' => $projectOptions,
'selection' => $oa->project_id
);

dropdown_field($mylist);

Within your array you have $projectOptions, which is likely another array - the one that outputs the option list.

I imagine dropdown_field looks something like this. Remember that the array "$mylist" now turns into the array "$attributes" once it's passed to the function. Remember how I said any variables inside a function are not affected by variables outside the function? I'm going to demonstrate that by using the same variable - $mylist - inside the function to compose our dropdown.


function dropdown_field($attributes) {
//
$mylist = "<label for=\"" . $attributes['project_id'] . "\">" . $attributes['label'] . "</label>
<select name=\"" . $attributes['name'] . "\" id=\"" . $attributes['project_id'] .
class=\"" . $attributes['class'] . "\">";
// These may be reversed - that is, the label may be on the left, value on the right
foreach ($attributes['options'] as $optionvalue => $optionlabel) {
$mylist .= <option value=\"$optionvalue\"";
if (isset($attributes['selection']) and $attributes['selection']==$optionvalue)) { $mylist .= ' selected'; }
// Or selected="selected" for XHTML :-/
$mylist .= ">$optionlabel</option>\n";
}
$mylist .= '</select>';
echo $mylist;
// THIS SHOULD BE
// return $mylist;
// see below
}


If I haven't lost you, if you examine these carefully, it will all make sense: an array is passed to a function and it operates on the array to create a dropdown list. Note the last comments: this should return a value. But likely, you may not be able to. In my version I concatenate the list into a string (scalar) then output it once. There is a trend, what I consider a bad habit, to do this.

echo "<label for=\"" . $attributes['project_id'] . "\">";
echo $attributes['label'];
echo "</label> <select name=\"";
echo $attributes['name'] . "\" id=\"" . $attributes['project_id'];

... etc. Echo as you go. The argument for this approach is that it frees memory and that concatenation as I've done consumes memory. The latter is partly true, but the amount of memory used by concatenating even a whole page is very minimal. It also allows you to code a little more gracefully, making your apps easier to manage. Too many times I've chased an errant echo which appeared in some uncomfortable spot on a page.

Another argument against "print as you go" is that if you've ever encountered an already-bloated page operating on a slow server, you may have seen pages load the top third . . . then half . . . then 3/4 . . . then finally the whole thing . . . or stop loading completely halfway down the page. This is a result of "print as you go" programming (but likely has more serious problems causing it to output very slowly.) If my app is so slow it would do this, I'd rather have them not see anything at all until I fix it. :-)

So if you return a value from a function, you can now do this

$this_list = dropdown_field($mylist);

and "$this_list" can go anywhere you need it to.

Pointers are for the next lesson I think. :-)

highseas

5:30 pm on May 27, 2011 (gmt 0)

10+ Year Member



rocknbil -- thanks for getting back to me, I am going to dive into your post right now!

rocknbil

5:52 pm on May 27, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



<cough> typo

$mystring = $this_string . " world";

should be

$mystring = $the_string . " world";

All typed on the fly . . . not straight copy and paste, for example only . . .

highseas

10:11 pm on May 27, 2011 (gmt 0)

10+ Year Member



haha just saw that, i am looking at your helpful answer right now