• PHP Help PHP Coding
  • [Resolved] php doesn't "see" a global array when it really, really should

Is there some small nuance of the php language I am not aware of?

This code appears in a file that is include()'d, if that is significant.

<?php 

$myarray = array( etc );

class someclass
{



}

function myfunction()
{
 GLOBAL $myarray;
 foreach ($myarray as $key=>$val) { 

 }
}

class anotherclass
{

}

?>

PHP says saying there is an invalid argument in foreach. When I move the array declaration inside the function that uses it, the code works. I want my array to be global though, because it is also needed in someclass to dynamically build some links.

Can anyone point out why PHP a function wouldn't recognize a variable declared outside of any control structures when I've used GLOBAL $myarray to import it? It's. Really. Frusterating.

    The code works for me (the classes don't seem to be doing anything?). It might be an include() issue...do you try to foreach() the array before it's been included?

      I'm guessing it's some kind of funky include issue. When I print the array contents just outside of the function, they work, but nothing short of passing it into the function as an argument will make the function see the array.

      I had rather hoped someone would know of a better way to handle this though. I even tried declaring my array as a array inside my superglobal wrapper $data->vars['array'] = array() and the function still says invalid argument in foreach.

        Hi,

        Please post the complete script (as attachment). Does the code always set that array or is that array part of e.g. an if...else statement ?

        Add

        print_r($GLOBALS);
        

        to the function to see which global variables are set.

        Thomas

          I think that this may be where your problem is. From the manual

          References with global and static variables

          The Zend Engine 1, driving PHP 4, implements the static and global modifier for variables in terms of references. For example, a true global variable imported inside a function scope with the global statement actually creates a reference to the global variable. This can lead to unexpected behaviour which the following example addresses:

          <?php
          function test_global_ref() {
          global $obj;
          $obj = &new stdclass;
          }

          function test_global_noref() {
          global $obj;
          $obj = new stdclass;
          }

          test_global_ref();
          var_dump($obj);
          test_global_noref();
          var_dump($obj);
          ?>

          Executing this example will result in the following output:

          NULL
          object(stdClass)(0) {
          }

            Probable solution would be to use the superglobal $GLOBAL to store the array.

              ...a better way to handle this...

              Since you asked...

              A better way to handle it would be to pass the array to your function and/or to a class method. For instance:

              $someobject->set_my_class_array($myarray);

              Globals are used much more often than they're needed, and they defeat a purpose of both functions and classes.

                I got around the problem using the $GLOBAL array.

                Here's the module, if anyone wants to see the specifics. I can't pass the array to the function because class that calls the function buildrow(), near the bottom, is in another file and is used rather generically to drive my modules.

                <?php
                
                /*
                   +---------------------------------+
                   | Seir Anphin v2.0.0              |
                   | by Darrel Grant (c) 2004,2005   |
                   +---------------------------------+
                   | Wordbit Administration Module   |
                   | Module Version: 1.0.0           |
                   | Module Author: Darrel Grant     |
                   +---------------------------------+
                */
                
                class admin_wordbit extends module_base
                {
                	var $wordbit_groups = array();
                
                function admin_wordbit()
                {
                	GLOBAL $GLOBAL,$data;
                
                	$this->wordbit_groups = array('1' => 'Miscellaneous Messages',
                								  '2' => 'Registered User Feedback',
                								  '3' => 'Forum Wordbits',
                								  '4' => 'Shrine Wordbits',
                								  '5' => 'Datagroup Module Wordbits',
                								  '6' => 'Control Panel Wordbits');
                
                	// work-around php's silly blindness when it comes to globals and functions...
                	$GLOBAL['wordbitgroups'] = &$this->wordbit_groups;
                
                	if (!isadmin()) {
                		setstatus(getwordbit('cp_accessdenied'));
                		return loadmodule('index', 'frontpage');
                	}
                
                	loadtemplates('controlpanel');
                	$this->default_page = 'show';
                	$data->vars['globalvars']['section'] = getwordbit('wordbit_section_title');
                }
                
                function add($oldinput = '')
                {
                	if (!is_array($oldinput)) $oldinput = array('name'=>'', 'groupid'=>'1', 'value'=>'');
                
                	doinclude('formlib');
                	$f = new form;
                
                	$f->formtop("index.php?m=admin_wordbit&op=build");
                	$f->getform('header', getwordbit('wordbit_add_form_header'));
                	$f->getform('text', getwordbit('wordbit_add_form_name'), 'name', $oldinput['name']);
                	$f->getform('custom', getwordbit('wordbit_add_form_group'), getwordbitgroups($oldinput['groupid']));
                	$f->getform('textarea', getwordbit('wordbit_add_form_value'), 'value', $oldinput['value']);
                	$f->getform('submitreset', getwordbit('wordbit_add_form_submit'), getwordbit('wordbit_add_form_reset'));
                	$f->formbottom();
                
                	return gettemplate('controlpanel', $f->getoutput());
                }
                
                function build()
                {
                	GLOBAL $dbr;
                
                	$p = getpostvars('name,groupid,value');
                	if (!$p) return $this->show();
                
                	if ($p['name'] == '' || $p['value'] == '') return $this->add($p);
                
                	$dbr->query("INSERT INTO wordbits SET ".buildsql($p, 'addslashes'));
                
                	setstatus(getwordbit('wordbit_built', array('wordbitname'=>$p['name'])));
                	return $this->add($p);
                }
                
                function delete()
                {
                	GLOBAL $dbr,$HTTP_POST_VARS;
                
                	$name = $dbr->result("SELECT name FROM wordbits WHERE wordbitid=$this->id");
                
                	if (empty($HTTP_POST_VARS['confirm'])) {
                		return gettemplate('controlpanel', showmsg("<form action=\"index.php?m=admin_wordbit&op=delete&id=$this->id\" method=\"post\">
                						  Are you sure you want to delete wordbit $name?<br>
                						  <input type=\"hidden\" name=\"confirm\" value=\"1\" />
                						  <input type=\"submit\" value=\"Yes, I'm sure\" />
                						</form>"));
                	}
                
                	$dbr->query("DELETE FROM wordbits WHERE wordbitid=$this->id");
                	setstatus(getwordbit('wordbit_deleted', array('wordbitname'=>$name)));
                	return $this->show();
                }
                
                //----------------------------------------------------------------------------------
                // Wordbits are edited through the display mechanism which creates has two arrays where index
                // is wordbit ID and array name is values or groups. These are then saved en masse.
                //----------------------------------------------------------------------------------
                function show()
                {
                	GLOBAL $dbr,$HTTP_GET_VARS;
                
                	if ($this->id != 0) $where = "WHERE groupid='$this->id'";
                	else $where = '';
                
                	loadsettings('wordbit_list_limit');
                	$l = new wordbitlist;
                
                	$str = '<select name="id">';
                	foreach ($this->wordbit_groups as $key=>$val) {
                		$str .= "<option value=\"$key\">$val</option>\n";
                	}
                	$str .= '</select>';
                
                	return gettemplate('controlpanel', $l->buildlist("SELECT * FROM wordbits $where ORDER BY name ASC",
                	'adminwordbitlist',
                	array('groups_select' => $str),
                	getsetting('wordbit_list_limit'),
                	$dbr->result("SELECT COUNT(wordbitid) FROM wordbits $where")));
                }
                
                //----------------------------------------------------------------------------------
                // Saves any number of wordbits where $_POST['values'] is an array of values and
                // $_POST['groups'] is an array of wordbit groups.
                //----------------------------------------------------------------------------------
                function save()
                {
                	GLOBAL $HTTP_POST_VARS,$dbr;
                
                	if (empty($HTTP_POST_VARS['values'])) return $this->show();
                
                	$values = $HTTP_POST_VARS['values'];
                	$groups = $HTTP_POST_VARS['groups'];
                
                	foreach ($values as $wordid=>$content) {
                		$dbr->query("UPDATE wordbits SET value='".addslashes($content)."', groupid=$groups[$wordid] WHERE wordbitid=$wordid");
                	}
                
                	setstatus(getwordbit('wordbits_updated'));
                	return $this->show();
                }
                }
                
                //----------------------------------------------------------------------------------
                // Returns a select menu which can automatically highlight a wordbit group
                //----------------------------------------------------------------------------------
                function getwordbitgroups($select_group = '', $multi = FALSE, $id = 0)
                {
                	GLOBAL $GLOBAL;
                
                if ($multi) $str = "\n<select name=\"groups[$id]\">";
                else $str = "\n<select name=\"groupid\">";
                
                foreach ($GLOBAL['wordbitgroups'] as $groupid=>$name) {
                	if ($groupid == $select_group) {
                		$str .= "\n<option selected=\"selected\" value=\"$groupid\">$name</option>";
                	} else {
                		$str .= "\n<option value=\"$groupid\">$name</option>";
                	}
                }
                $str .= "\n</select>";
                return $str;
                }
                
                
                class wordbitlist extends sql_list
                {
                	function buildrow($a)
                	{
                		$a['groups'] = getwordbitgroups($a['groupid'], TRUE, $a['wordbitid']);
                		$a['rows'] = ceil(strlen($a['value']) / 40) + 1;
                		$a['altclass'] = rowswitch('cell', 'altcell');
                		return array_replace($a, $this->rowtemplate);
                	}
                }
                
                ?>
                
                  Write a Reply...