Getting back information added with multiple calls to a function - php

I want to have a function and then use it multiple times with different parameters.
For example:
<?php
class Test {
var $test;
public function func($val) {
$this->test = $val;
}
public function buildFunc() {
if(!empty($this->test)) {
$ret = $this->test;
}
return $ret;
}
}
?>
Then on calling page:
$test = new Test;
$test->func("test1");
$test->func("test2");
echo $test->buildFunc();
Then it prints test2 on the screen. And I want it to print out both of them.

Either create 2 instances of your object;
$test1 = new Test;
$test1->func("test1");
$test2 = new Test;
$test2->func("test2");
echo $test1->buildFunc();
echo $test2->buildFunc();
Or make test an array;
class Test {
var $test = array();
public function func($val) {
$this->test[] = $val;
}
public function buildFunc() {
return print_r($this->test, true);
}
}

May be you mean that you want to store all values? Then use an array:
public function func($val) {
$this->test[] = $val;
}
public function buildFunc() {
return $this->test
}
And then work with the result as with an array.

Well.. your code does exactly what are you telling it to do. Consider situation when you have no OOP:
$str = 'test 1';
$str = 'test 2';
echo $str; //prints test 2
So you need to echo them separately as if it wont be an OOP situation.
$test = new Test;
$test->func("test1");
echo $test->buildFunc();
$test->func("test2");
echo $test->buildFunc();

When calling the method create 2 instances of the test object.
$test = new Test;
$test->func("test1");
echo $test->buildFunc();
$test2 = new Test;
$test2->func("test2");
echo $test2->buildFunc();
if you dont want to create 2 instances you have to make a array instead.

How about create a constructor and initialize the value of test and concat the second value.
<?php
class Test {
var $test;
public function __construct($init){
$this->test = $init;
}
public function func($val) {
$this->test .= $val;
return $this;
}
public function buildFunc() {
if(!empty($this->test)) {
$ret = $this->test;
}
return $ret;
}
}
$test = new Test("test1");
$test->func("test2");
echo $test->buildFunc();
?>

When you say both do you mean something like
test1test2
or do you want
test1
test2
For the first option you can just append the string:
<?php
class Test {
var $test;
public function func($val) {
$this->test = $test . $val; <-- add val to the end
}
public function buildFunc() {
if(!empty($this->test)) {
$ret = $this->test;
}
return $ret;
}
}
?>
For the second:
<?php
class Test {
var $test = array();
public function func($val) {
$this->test[] = $val; <-- add val to
}
public function buildFunc() {
if(!empty($this->test)) {
foreach($test as $item){
echo $item . "<br/>";
}
}
}
}
?>

Push the variables to an array
<?php
class Test {
var $test;
public function __construct(){
$this->test=array();//Declare $test as an array
}
public function func($val) {
$this->test[]=$val;//Push to array
}
public function buildFunc() {
if(!empty($this->test)) {
$ret = implode(",",$this->test);
}
return $ret;
}
}
?>

Related

Define value of class when assigned to variable in PHP

In PHP I can use \ArrayAccess to create an object such that it can be assigned as variable (an array) but also execute some other stuff while doing it, is it possible to do the same with a single value variable?, for example:
$a = new MyClass(5, "some other stuff")->print(); //Prints 'some other stuff'
$b = $a * 2;
echo $b; //Prints 10
The idea would be that the first parameter is returned when the variable is assigned but at the same time I can do something else with the second parameter, so far I have only manage to do it ussing the __invoke magic method, but the end result is something like this:
$a = new MyClass(5, "some other stuff")->print(); //Prints 'some other stuff'
$b = $a() * 2;
echo $b; //Prints 10
Is it possible to do it without the __invoke method?
This is the way I managed to do it with \ArrayAccess (just in case it helps)
class MySQLK_customArray implements \ArrayAccess{
private $storage = array();
private $queryk;
public function __construct($fetch_array, $query){
$this->queryk = $query;
$this->storage = $fetch_array;
}
public function offsetSet($key, $value)
{
if (is_null($key)) {
$this->storage[] = $value;
} else {
$this->storage[$key] = $value;
}
}
public function offsetExists($key)
{
return isset($this->storage[$key]);
}
public function offsetUnset($key)
{
unset($this->storage[$key]);
}
public function offsetGet($key)
{
if (! isset($this->storage[$key])) {
return null;
}
$val = $this->storage[$key];
if (is_callable($val)) {
return $val($this);
}
return $val;
}
public function print(){
echo $this->queryk.";";
return $this;
}
public function get(){
return $this->storage;
}
}
It can be used this way:
$arr = new MySQLK_customArray(array("id" => 1),"SELECT * FROM Table LIMIT 1")->print(); //Prints 'SELECT * FROM Table LIMIT 1'
echo $arr['id']; //Prints 1

How to call the function by variable

I hope this question is not too simple, but I have no idea how to do this
$book = 'book';
$car = 'car';
function $book()
{
return "Hello, world!";
}
function $car()
{
return "WoW , The red car";
}
You cant do that, you have 2 options.
A couple of ways:
Use variable functions:
<?php
$book = 'book';
$car = 'car';
function book()
{
return "Hello, world!";
}
function car()
{
return "WoW , The red car";
}
echo $book();
echo $car();
Or closures:
<?php
$book = function () {
return "Hello, world!";
};
$car = function() {
return "WoW , The red car";
};
echo $book();
echo $car();
You can write an anonymous function:
$book = function() {
return "Hello, world!";
};
echo $book(); // invoke it
Class
class foo
{
public function __invoke(){ echo "hello"; }
}
Test
$obj = new foo;
$obj();
Output
hello
Online Sandbox
You can also use reflection (to call an existing function as a string)
(new ReflectionFunction('print_r'))->invoke("hello");
Outputs
hello
ReflectionMethod is nice too, because it maintains state of the object, for example
class foo{
protected $bar;
public function setBar($bar){ $this->bar = $bar;}
public function bar(){ echo $this->bar; }
}
$obj = new foo;
$obj->setBar("good bye");
(new ReflectionMethod($obj, 'bar'))->invoke($obj);
Outputs
good bye
You can call a function with variable name like this:
Variable functions
<?php
$a = 'book';
function book() {
echo 'book function';
}
// this is equivalent to book()
$a();
So to expand a little bit:
<?php
$functions = ['book', 'car'];
function book() {
return "Hello, world!";
}
function car() {
return "WoW , The red car";
}
foreach ($functions as $function) {
echo $function() .'<br>';
}
The OUTPUT would be:
Hello, world!
WoW , The red car
Another way of doing it to get same output:
Anonymous functions
$book = function() {
echo 'book function';
};
$book();
In this case, the above function doesn't have an actual name and is represented by a variable.
And let me give you an example:
<?php
$book = function() {
echo 'book function';
};
$a = $book;
echo $a();
So, to expand in the same manner:
<?php
$functions = ['book', 'car'];
$book = function () {
return "Hello, world!";
};
$car = function() {
return "WoW , The red car";
};
foreach ($functions as $function) {
echo ${$function}(). '<br>';
}
DEMO:
http://sandbox.onlinephpfunctions.com/code/1972f1acd72984d459efbfb308680aaa9d7a1fad

Returning references with or without a function

Are there any actual difference between the two ways to get the value by reference?
Way 1
<?php
class foo {
public $value = 42;
public function &getValue() {
return $this->value;
}
}
$obj = new foo;
$myValue = &$obj->getValue();
// $myValue is a reference to $obj->value, which is 42.
$obj->value = 2;
echo $myValue;
// prints the new value of $obj->value, i.e. 2.
?>
Way 2
<?php
class foo {
public $value = 42;
public function getValue() {
return $this->value;
}
}
$obj = new foo;
$myValue = &$obj->value;
$obj->value = 2;
echo $myValue;
?>
In both cases 2 is printed. So why does one need the getValue() function then? The first example is taken from the PHP Manual.
You need the first approach if class fields don't have a modifier 'public'. In this case you can't get a reference to the field outside the class. See example:
<?php
class foo
{
protected $value = 1;
public function setValue($value)
{
$this->value = $value;
}
public function &getValue()
{
return $this->value;
}
}
$obj = new foo;
$myValue = &$obj->getValue();
$obj->setValue(2);
echo $myValue;
?>

PHP: passing class member by reference not working

Someone asked for an event handler that registeres variable changes in this question: PHP how to detect the change of variable?
I tried to develop a quick class with PHP's magic functions __get and __set. This works until I pass the member into a normal function by reference, it does not trigger the event anymore.
Is this a bug, or something that is not possible, or do I just miss something?
<?php
header("content-type: text/plain");
class WatchVar {
private $data = array();
private $org = array();
private $callbacks = array();
public function __set($name, $value) {
if (!array_key_exists($name, $this->data)) {
$this->org[$name] = $value;
} else {
//variable gets changed again!
$this->triggerChangedEvent($name, $value);
}
$this->data[$name] = $value;
}
public function &__get($name) {
if (array_key_exists($name, $this->data)) {
if ($this->data[$name] != $this->org[$name]) {
//variable has changed, return original
//return $this->org[$name];
//or return new state:
return $this->data[$name];
} else {
//variable has not changed
return $this->data[$name];
}
}
}
public function addCallback($name, $lambdaFunc) {
$this->callbacks[$name] = $lambdaFunc;
}
protected function triggerChangedEvent($name, $value) {
//$this->data[$name] has been changed!
//callback call like:
call_user_func($this->callbacks[$name], $value);
}
}
$test = new WatchVar;
$test->addCallback('xxx', function($newValue) { echo "xxx has changed to {$newValue}\n"; });
$test->xxx = "aaa";
echo $test->xxx . "\n";
//output: aaa
$test->xxx = "bbb";
//output: xxx has changed to bbb
echo $test->xxx . "\n";
//output bbb
function messyFunction(&$var) {
$var = "test";
}
messyFunction($test->xxx);
//output: nothing, why?
Altering this code it works:
function messyFunction(&$var) {
$var->xxx = "test";
}
messyFunction($test);
//output: xxx has changed to test
//output: nothing, why?
Even passed by reference, the function only recieves a clone of the member variable instead of the instance + magic functions.

PHP function in a function

I am trying to build a function that will call another function.
For example, if I have an array full of function names to call, is it possible to call a function for every array value without writing it in a script?
Example:
function email($val=NULL) {
if($val)
$this->_email = $val;
else
return $this->_email;
}
function fname($val=NULL) {
if($val)
$this->_fname = $val;
else
return $this->_fname;
}
For email, fname, etc.
But I want to have it like:
function contr_val($key,$val) {
function $key($val=NULL) {
if($val)
$this->_$key = $val;
else
return $this->_$key;
}
function $key($val="hallo");
}
And call it with:
contr_val("email", "test")
You're really trying to create member variables dynamically and retrieve their values. This is what __get() and __set() are for.
Here's how you could use it:
class TestClass {
var $data = array();
public function __set($n, $v) { $this->data[$n] = $v; }
public function __get($n) {
return (isset($this->data[$n]) ? $this->data[$n] : null);
}
public function contr_val($k, $v = NULL) {
if ($v)
$this->$k = $v;
else
return $this->$k;
}
};
$sherp = new TestClass;
$sherp->contr_val("Herp", "Derp");
echo "Herp is: " . $sherp->contr_val("Herp") . "\n";
echo "Narp is: " . $sherp->contr_val("Narp") . "\n";
Something like this:
/*
Input: $val - any value
$varname - the variable name, for instance: _email
*/
function checkValue($val=NULL, $varname) {
if($val)
$this->$var = $val;
else
return $this->$var;
}
checkValue("hello", "_email");
checkValue("hello2", "_name");
If you are doing this for a class, consider using PHP's magic methods __get() and
__set().
In an array full of function names, this calls every function that exists.
ghoti#pc:~$ cat functest.php
#!/usr/local/bin/php
<?php
function one() { print "one\n"; }
function two() { print "two\n"; }
function three() { print "three\n"; }
$a=array( "one", "two", "three", "four" );
foreach ($a as $item) {
if (function_exists($item)) {
$item();
} else {
print "No such function: $item\n";
}
}
ghoti#pc:~$ ./functest.php
one
two
three
No such function: four
ghoti#pc:~$
You need to check if the function exists or not:
function contr_val($key,$val) {
if (!function_exists($key)) {
function $key($val=NULL) {
if ($val)
$this->_$key = $val;
}
}
else {
return $this->_$key;
}
}

Categories