Overloading and Array - php

<?php
class MaClasse
{
private $attributs = array();
private $unAttributPrive;
public function __get ($nom)
{
if (isset ($this->attributs[$nom]))
return $this->attributs[$nom];
}
public function __set ($nom, $valeur)
{
$this->attributs[$nom] = $valeur;
}
public function afficherAttributs()
{
echo '<pre>', print_r ($this->attributs, true), '</pre>';
}
}
$obj = new MaClasse;
$obj->attribut = 'Simple test';
$obj->unAttributPrive = 'Autre simple test';
echo $obj->attribut;
echo $obj->autreAtribut;
$obj->afficherAttributs();
?>
I don't understand why the second variable does not show anything?
But in the array it does exist.

You're setting unAttributPrive, but getting autreAtribut.

I'm gonna go out on a whim and guess because you are spelling your variable names wrong. If you are looking to echo $obj->unAttributPrive

Related

Array reference in a class error in php

I have this class which populates and prints an array
<?php
class testArray
{
private $myArr;
public function __construct() {
$myArr = array();
}
public static function PopulateArr() {
$testA = new testArray();
$testA->populateProtectedArr();
return $testA;
}
protected function populateProtectedArr()
{
$this->myArr[0] = 'red';
$this->myArr[1] = 'green';
$this->myArr[2] = 'yellow';
print_r ($this->myArr);
}
public function printArr() {
echo "<br> 2nd Array";
print_r ($this->myArr);
}
}
?>
I instantiate this class from another file and try to print the array in different function.
<?php
require_once "testClass.php";
$u = new testArray();
$u->PopulateArr();
$u->printArr();
?>
I am not able to print the array in the printArr() function. I want to get reference to the array that I had set the values in .
You just missed one thing, you have to assign result of $u->PopulateArr(); to $u again, otherwise you will not get the object you created from that method call, so:
$u = new testArray();
$u = $u->PopulateArr(); // this will work
$u->printArr();
This also can be done like this:
$u = testArray::PopulateArr();
$u->printArr();
It seems that your $u object never populates the private array.
Instead you create a new object $testA and populate its array.
This might help you understanding the way
class testArray
{
private $myArr;
public function __construct() {
$this->myArr = array();
}
public static function PopulateArr() {
$testA = new testArray();
$testA->populateProtectedArr();
return $testA;
}
protected function populateProtectedArr()
{
$this->myArr[0] = 'red';
$this->myArr[1] = 'green';
$this->myArr[2] = 'yellow';
return $this->myArr;
}
public function printArr() {
echo "<br> 2nd Array";
return $this->PopulateArr();
}
}
another.php
require_once "testClass.php";
$u = new testArray();
print_r($u->PopulateArr());
print_r($u->printArr());
Here we are accessing the values of protected function PopulateArr instead of printing within function I just replaced it with return and print it over another file and within printArr function just call the PopulateArr function and that's it

Only initialize a variable in an array if it's requested

Here's a little mock-up to describe my predicament:
<?php
$var = "Before";
function getVar(){
global $var;
return $var;
}
$array = Array(
"variable" => "Var = " . getVar()
);
$var = "After";
echo $array['variable'];
?>
That code would echo 'Before', I'm aiming for it to echo 'after'. I realize that this is how PHP is supposed to work however it's crucial for the array to execute getVar() only when it's called.
How would I go about doing this?
You can not do this since array declaration will initialize it - so you're mixing function calling at array's 'usage' and at it's definition. There's no 'usage': array is already defined to that moment.
However, an answer could be using ArrayAccess, like this:
class XArray implements ArrayAccess
{
private $storage = [];
public function __construct()
{
$this->storage = func_get_args();
}
public function offsetSet($offset, $value)
{
if(is_null($offset))
{
$this->storage[] = $value;
}
else
{
$this->storage[$offset] = $value;
}
}
public function offsetExists($offset)
{
return isset($this->storage[$offset]);
}
public function offsetUnset($offset)
{
unset($this->storage[$offset]);
}
public function offsetGet($offset)
{
if(!isset($this->storage[$offset]))
{
return null;
}
return is_callable($this->storage[$offset])?
call_user_func($this->storage[$offset]):
$this->storage[$offset];
}
}
function getVar()
{
global $var;
return $var;
}
$var = 'Before Init';
$array = new XArray('foo', 'getVar', 'bar');
$var = 'After Init';
var_dump($array[1]);//'After Init'
-i.e. try to call data, which is inside element, when actual get happened. You may want to have different constructor (for associative arrays) - but the general idea was shown.
Editing my answer after the question was edited.
No, what you are trying to achieve isn't possible because when you call the function it returns and it's done at that point. But you could achieve something similar with object oriented coding. I'll create something for you, please wait.
<?php
class Foo {
public function __toString() {
global $var;
return "Var = {$var}";
}
}
$var = "Before";
$array = array( "variable" => new Foo() );
$var = "After";
echo $array['variable'];
?>
PS: Sorry for the late answer, but there was a blackout in Salzburg. :(
It occurred to me that you could also use anonymous functions and invoke/execute those
Proof of concept:
$var = "Before";
function getVar(){
global $var;
return $var;
}
$array = Array(
"variable" => create_function(null, "return 'Var = ' . getVar();")
);
$var = "After";
echo $array['variable']();
returns
Var = After

Passing a variable to its parent function in PHP?

I have a function w/in a function, and I need the inner function to make it's variables available in a scope of parent function, e.g.:
function sayMyName(){
getName(); // inner function generates $name value
echo $name; // use $name
}
sayMyName();
I could easily just globalize things w/in both functions... But my situation is far more complicated and handles more variables and globalizing each one is a bit tedious.
Thanks.
PS
i noticed a lot of "return" suggestions. sorry i wasnt clear , i need to return more variables.. not a simple return. thanks guys
You may use $_GLOBALS, but it`s a "bad practice". So,
1: Use return:
<?php
function getName(){
$name = 'Smith';
return $name;
}
function sayMyName(){
$name = getName();
echo $name;
}
sayMyName();
?>
Shows:
Smith
2: Use references:
<?php
function getName(&$name){
$name = 'Smith';
}
function sayMyName(){
getName($name);
echo $name;
}
sayMyName();
?>
Shows:
Smith
3: Return array for multiple variables:
<?php
function getName(){
$surname = 'Smith';
$name = 'John';
return array($surname, $name);
}
function sayMyName(){
list($surname, $name) = getName();
echo $name, ' ', $surname;
}
sayMyName();
?>
Shows:
John Smith
4. Return custom object for multiple variables:
<?php
function getName(){
$surname = 'Smith';
$name = 'John';
$buffer = new stdClass();
$buffer->name = $name;
$buffer->surname = $surname;
return $buffer;
}
function sayMyName(){
$obj = getName();
echo $obj->name, ' ', $obj->surname;
}
sayMyName();
?>
Shows:
John Smith
5. Use anonymous function with use statement and references:
<?php
function sayMyName(){
$surname = $name = 'Unknown';
$temp = function() use (&$name, &$surname){
$surname = 'Smith';
$name = 'John';
};
$temp();
echo $name, ' ', $surname;
}
sayMyName();
?>
Shows:
John Smith
do this
function sayMyName(){
$name = getName(); // inner function generates $name value
echo $name; // results will be returned
}
sayMyName();
I hope your inner function is returning name like this
function getName(){
return $name;
}
then it will work
This is what the object oriented programming was designed for. If many functions should share variables, it is probably best to encapsulate them to class like this:
class WhateverDescibestYourViewOfTheWorld {
protected $name;
function __construct( $name)
{
$this->name = $name;
}
function GetName() {
return $this->name;
}
function SayName()
{
echo $this->name;
}
}
// And use it:
$o = new WhateverDescibestYourViewOfTheWorld();
...
$o->SayName();
Or you can build class which will be just used as data container:
class DataContainer {
public $name;
public $address;
// ...
}
// By reference this will modify object previously created
function GetProperties( &$dataContainer) // Note that & isn't necessary since PHP5
{
$dataContainer->name = "...";
}
$c = new DataContainer();
GetProperties($c);
Or you can simplify this and use array:
function GetProperties( array &$dataContainer)
{
$dataContainer['name'] = '...';
}
$data = array();
GetProperties($data);
What about first assigning the return value of getName() to a variable?
$name = getName();
If you only need one variable you can do this
function getName(){
// Some code
return 'my name is XXX';
}
function sayMyName(){
$name = getName(); // inner function generates $name value
echo $name; // results to undefined
}
sayMyName();
Otherwise you may consider using a class : http://www.php.net/manual/en/language.oop5.php
You can use references
$param = "aaa";
function f(&$param)
{
//dostuff
inner($param);
echo $param;
}
function inner(&$inner) { //do other stuff }
or use return value
function f() { echo inner(); }
function inner($param) {return $param;}
if you work on references, both functions will work on same variable, not on a copy
http://php.net/manual/en/language.references.php
the best way would be with class
<?php
class Person
{
private $name;
public function setName($name){ $this->name = $name;}
public function sayName() {echo $this->name;}
}
$person = new Person();
$person->setName("Robert");
$person->sayName();
It's good way to make it in OOP.
That what you are thinking is wrong, however you can return an array of values. For ex:
function sayMyName()
{
$result = getName(); // inner function creates an array
echo $result['name'];
}
or better an object:
class Results
{
public $name;
}
function sayMyName()
{
$result = getName(); // inner function creating an object
echo $result->name;
}
You can also do it as below.
$name = "";
function sayMyName(){
getName(); // inner function generates $name value
//set $name variable inside getName() function.
echo $name; // results to undefined
}
sayMyName();
Please use bellow code ,it will solve your problem
global $var;
You can use it anywhere within your php span.

php scope issue for function checking isset

I need a function that will take a string as an argument, then check to see if a variable named the same thing as that string is set.
This works...
$foo = 'foosuccess';
$property = 'foo';
if(isset($$property)){
echo $$property;
}
This doesn't, because within test(), $$property2 is the wrong scope.
$huh = 'huhsuccess';
$huh = test("huh");
function test($property2){
if(isset($$property2)){
echo $$property2;
}
}
How can I fix the function so $$property2 refers to the same scope as the caller's context? Is that possible?
Thanks in advance....
try this:
$huh = 'huhsuccess';
test("huh");
function test($property2) {
global $$property2;
if(isset($$property2)) {
echo $$property2;
}
}
<?php
function test($s)
{
return isset($GLOBALS[$s]);
}
ok, i think i figured it out for my purposes (if anyone's interested...)
//uncomment to get success
//$huh = 'huhsuccess';
$huh = test($huh);
echo $huh;
function test(&$property2) {
if(isset($property2)) {
return $property2;
} else {
return 'not set!';
}
}
die;
This can be done with eval():
$foo = 'foosuccess';
$property = 'foo';
if(eval('isset($'.$property.')'){
echo $$property;
}

Problem with __get and __set code

I don't know where I am doing wrong. Can somebody show me?
<?php
class something
{
public $attr1;
private $attr2;
public function __get($name)
{
return $this->$name;
}
public function __set($name,$value)
{
$this->$name = $value." added something more";
}
}
$a = new something();
$a->$attr1 = "attr1";
$a->$attr2 = "attr2";
echo $a->$attr1; //what I would expect is attr1 as output
echo $a->$attr2; //what I would expect is attr2 added something more as output
?>
Remove the multiple instances of $ when accessing the object properties:
$a->$attr1 = "attr1"; $a->attr1 = "attr1";
$a->$attr2 = "attr2"; $a->attr2 = "attr2";
echo $a->$attr1; echo $a->attr1;
echo $a->$attr2; echo $a->attr2;

Categories