Undefined variable issue - php

There are 3 compilation errors in the init.php code:
Undefined variable $ind
Undefined variable $popsize
Undefined variable $chrom
How to solve this issue in the proper way?
main.php
include_once 'init.php';
class Individual {
public $genes = array();
//...
}
class Population {
public $ind = array();
public $ind_ptr;
public function setIndPtr(Individual $ind) {
$this->ind_ptr = $ind;
}
}
$popsize = 10;
$chrom = 5;
$pop = new Population();
$pop_ptr = new Population();
$pop = init(pop_ptr);
init.php
function init(Population $pop_ptr) {
$pop_ptr->setIndPtr($ind[0]);
for ($i = 0 ; $i < $popsize ; $i++) {
for ($j = 0; $j < $chrom; $j++) {
$d = rand(0,1);
if($d >= 0.5) {
$pop_ptr->ind_ptr->genes[$j] = 1;
}
else {
$pop_ptr->ind_ptr->genes[$j] = 0;
}
}
$pop_ptr->setIndPtr($ind[$i+1]);
}
$pop_ptr->setIndPtr($ind[0]);
return $pop_ptr;
}

Its a matter of scope: Variables are not shared over files, unless you make them global!
(Badly explained) variables such as
inc.php
$a=1;
main.php
include "inc.php";
print $a
would work
however
inc.php
function func()
{
$a=1;
}
main.php
include "inc.php";
func();
print $a;
a is not available.
Hope that makes it clearer.

Global variables in function scope need to be declared explicitly global before use:
<?php
function foo()
{
global $global_variable_from_outside_function_scope;
$global_variable_from_outside_function_scope += 1;
}
As for $ind, there's no such variable there. You want something more akin to $pop_ptr -> ind. Read the PHP docs again on classes, scope, etc..

Related

How can I create and execute a series of PHP Variable Functions in a for loop?

I'm unfamilar with using variable functions in PHP, but I've repeatedly re-read the manual:
https://www.php.net/manual/en/functions.variable-functions.php
and it's not at all clear what I'm doing wrong here:
for ($i = 0; $i < 10000; $i++) {
$Function_Name = 'Test_Function_'.sprintf('%03d', $i);
function $Function_Name() {
echo __FUNCTION__.' is working.';
}
$Function_Name();
}
Why is this loop not creating and running 10000 variable functions?
Alternative using anonymous functions
An alternative approach (using anonymous functions) doesn't seem to work either:
for ($i = 0; $i < 10000; $i++) {
$Function_Name = 'Test_Function_'.sprintf('%03d', $i);
${$Function_Name} = function () {
echo __FUNCTION__.' is working.';
}
${$Function_Name}();
}
Please note that anonymous (lambda) functions only see (closure) variables from the external scope if they are explicitly listed with "use" i.e.
${$Function_Name} = function () use ($Function_Name)
and then it works as expected.
for ($i = 0; $i < 10000; $i++)
{
$Function_Name = 'Test_Function_'.sprintf('%03d', $i);
${$Function_Name} = function () use ($Function_Name)
{
echo $Function_Name.' is working.'.PHP_EOL;
};
${$Function_Name}();
}

PHP Variable Variables within setter function

I am trying to achieve a way to define an indefinite, but not infinite number of variables, to be used to create objects. I have tried a couple of ways to try this but i cant seem to wrap my head around this.
Here is what i came up with:
$aCount= 0;
$Foo = "Bar".$aCount;
$$Foo = array("Data1"=>NULL, "Data2"=>NULL);
function getBarData1() {
return ${$Foo}['Data1'];
}
function getBarData2() {
return ${$Foo}['Data2'];
}
function setBarData($newBarData1, $newBarData2) {
${$Foo}['Data1'] = $newBarData1;
${$Foo}['CONTENT'] = $newBarData2;
$aCount++;
}
setBarData('First', 'Line');
setBarData('Second', 'Dot');
setBarData('Third', 'Dash');
for($aCount == $aCount; $aCount > -1; $aCount--) {
echo getBarData1() ."\n";
echo getBarData2() ."\n";
}
Any help would be greatly appreciated.
You are heading two problems:
variable scope
value of variable $Foo is static and never change - value is always: Bar0 even when you change $aCount because the value is just a string
working example:
<?php
$aCount= 0;
$Foo = function(){ global $aCount; return "Bar".$aCount; };
${$Foo()} = array("Data1"=>NULL, "Data2"=>NULL);
function getBarData1() {
global $Foo, ${$Foo()};
return ${$Foo()}['Data1'];
}
function getBarData2() {
global $Foo, ${$Foo()};
return ${$Foo()}['Data2'];
}
function setBarData($newBarData1, $newBarData2) {
global $aCount, $Foo, ${$Foo()};
${$Foo()}['Data1'] = $newBarData1;
${$Foo()}['Data2'] = $newBarData2;
$aCount++;
}
setBarData('First', 'Line');
setBarData('Second', 'Dot');
setBarData('Third', 'Dash');
$aCountTotal = $aCount;
for($i = 0; $i < $aCountTotal; $i++) {
$aCount = $i;
echo getBarData1() ."\n";
echo getBarData2() ."\n";
}
in this case you should use array instead, variable-variable is really usefull in rare cases
array example:
<?php
$arr = array();
function getBarData1($index) {
global $arr;
return $arr[$index]['Data1'];
}
function getBarData2($index) {
global $arr;
return $arr[$index]['Data2'];
}
function setBarData($newBarData1, $newBarData2) {
global $arr;
$arr[] = ['Data1' => $newBarData1, 'Data2' => $newBarData2];
}
setBarData('First', 'Line');
setBarData('Second', 'Dot');
setBarData('Third', 'Dash');
for($i = 0; $i < count($arr); $i++) {
echo getBarData1($i) ."\n";
echo getBarData2($i) ."\n";
}
better than using global variable in functions is passing data through parameters like:
<?php
$arr = array();
function getData1($array, $index) {
return $array[$index]['Data1'];
}
function getData2($array, $index) {
return $array[$index]['Data2'];
}
// reference to $array because we want to change the value
function setData(&$array, $newBarData1, $newBarData2) {
$array[] = ['Data1' => $newBarData1, 'Data2' => $newBarData2];
}
setData($arr, 'First', 'Line');
setData($arr, 'Second', 'Dot');
setData($arr, 'Third', 'Dash');
for($i = 0; $i < count($arr); $i++) {
echo getData1($arr, $i) ."\n";
echo getData2($arr, $i) ."\n";
}

Initialising an array of objects

Program that tests the rand function is an example:
<?php
class number {
function number() {
$occurences=0;
}
public $occurences;
public $value;
}
$draws = 5000;
$numOfInts = 10;
//$integers = array();
$integers [] = new number();
//initialising loop
for($i=0;$i<=$numOfInts;$i++)
$integers[$i]->$value = $i; //debugger points here
for($i=0;$i<$draws;$i++) {
$integers[rand(0,numOfInts)]->$occurences++;
}
foreach($integers as $int)
printf("%5d %5d <br/>",$int->$value,$int->$occurences);
?>
Errors on the WAMP server:
Undefined variable: value in C:\path\index.php on line 31
Fatal error: Cannot access empty property in C:\path\index.php on line 31
What caused them and how to fix it? I suppose that the $integers is declared incorrectly.
You should access members of an object with this syntax:
$integers[$i]->value
$integers[$i]->occurences;
However you have to initialize your array first as well which means un-comment the initial line to
$integers = array();
As a matter of fact you are not using the better OOP style which would change your data structure like this:
class Number {
private $value;
private $occurences = 0;
public function __construct($value = 0) {
$this->value = $value;
}
public function getValue() {
return $this->number;
}
public function addOccurence() {
$this->occurences++;
}
public function getOccurences() {
return $this->occurences;
}
}
You would then access the members like this:
// init part
$integers = array();
for($i = 0; $i < $numOfInts; $i++) {
$integers[] = new Number($i);
}
// draws part
for($i=0; $i < $draws; $i++) {
$integers[rand(0,$numOfInts-1)]->addOccurence();
}
// print part
foreach($integers as $number) {
printf("%5d %5d<br />", $number->getValue(), $number->getOccurences());
}
Why?
//$integers = array();
$integers [] = new number();
Should just be
$integers = array();
for($i=0;$i<=$numOfInts;$i++) {
$integers[$i] = new number();
}
There are no typed arrays in PHP

attempting to initialize php variables in constructor, getting error

I'm trying to initialize a class attribute within a php constructor method, but am getting the error:
Notice: Undefined variable: _board in C:\wamp\scaleUp\back\objects.php on line 9
code:
<?php
class Board {
public function __construct(){
for ($x = 9; $x >= 0; $x--) {
for ($y = 0; $y<10; $y++){
$row = array();
$row[$y] = $y;
}
$this->$_board = array();
$this->$_board[$x] = $row;
}
echo "here";
echo $this->$board[$x];
}
}
$board = new Board();
?>
The syntax to access an object field is $obj->field, not $obj->$field (unless you want to access the field name that is stored in $field).
Here, I have debugged the code for you.
<?php
class Board {
public $_board;
public function __construct(){
for ($x = 9; $x >= 0; $x--) {
for ($y = 0; $y<10; $y++){
$row = array();
$row[$y] = $y;
}
$this->_board = array();
$this->_board[$x] = $row;
}
echo "here";
echo $this->_board[$x+1];/*OR*/print_r($this->_board[$x+1]);
//$x had to be incremented here.
}
}
$board = new Board();
?>
As others mentioned, you have to follow the syntax: $obj->property, not $obj->$property.
remove the $ from _board -
$this->_board = array();
It should be
$this->board
You don't need the second $ sign.
Also, in your constructor, in the inner loop, you are re-initializing $row as an array in every iteration. Is that intended?
You have to define your variable as a member variable
suck as
class object {
$_board ;
...
...
...
}
and when you want to use it you have to use the following syntax
$this->_board = .....;
I hope this helps you

Conflicting static vars with non-static ones in changing values

Consider the following code:
class A {
private $a;
function f() {
A::a = 0; //error
$this->a = 0; //error
$self::a = 0; //error
}
}
How can I change $a in f()?
You were close. Either:
self::$a = 0; //or
A::$a = 0;
If it's static, or:
$this->a = 0;
If it's not.
I believe the syntax is:
self::$a
obviously we all have been tricked by the title of the question, though here is how you change $a's value.
<?php
class A {
private $a;
function f() {
//A::a = 0; //error
$this->a = 10; //ok
//$self::a = 0; //error
}
function display() {
echo 'a : ' . $this->a . '<br>';
}
}
$a = new A();
$a->f();
$a->display();
?>
Output:
a : 10
if you want $a to be static use the following:
<?php
class A {
private static $a;
function f() {
//A::$a = 0; //ok
//$this->a = 10; //Strict Standards warning: conflicting the $a with the static $a property
self::$a = 0; //ok
}
function display() {
echo 'a : ' . self::$a . '<br>';
}
}
$a = new A();
$a->f();
$a->display();
// notice that you can't use A::$a = 10; here since $a is private
?>

Categories