How can i copy an object? - php

I'm really stuck with references in php. In my programm i've got something similiar to this:
Programm
class Test
{
private $_property;
function __construct($property)
{
$this->_property = $property;
}
public function setProperty($property)
{
$this->_property = $property;
}
public function getProperty()
{
return $this->_property;
}
}
function doSmth(Test $var)
{
$newVar = new Test('test');
//I need to do something here...
}
$var = new Test('original');
doSmth($var);
var_dump($var);
Question
What should i do to copy all contents of $newVar variable to my $var variable so that i will be able to see it after using var_dump() function that is outside of function doSmth(). And i can't use getters and setters in my programm because i've got a lot of them and it will be a lot of code. Is it possible to solve this problem with my limitations?
UPDATE: I can't return value in my function doSmth() and i also tried __clone but nothing works. Can someone show me how can i do it with __clone()?

It is possible to create a copy of object by using a clone keyword. It will help you to create full replica of source object. OR, what I think also might be useful for you, you can try to pass Test object by reference:
function doSmth(Test &$var)
{
// Here you can do something with your var
}

$newVar only exists in the context of the function.
What you want to do is to create a return value like this:
function doSmth(Test $var)
{
$newVar = new Test('test');
//I need to do something here...
return $newVar;
}
and call the function like this instead:
$myNewShinyVar=doSmth($var);
This way, your function returns the object of the class Test as a a return value.
var_dump($myNewShinyVar);
Edit: If you cannot return a value, you can pass by reference instead:
function doSmth(&$var)
{
$var = new Test('test');
}
This will modify the variable itself that is passed as a parameter to it (rather than passing a copy of it)
doSmth($var);
var_dump($var);

If I read your question a number of times I think is this what you are after:
function doSmth(Test $var)
{
$newvar = clone $var;
// do some stuff on a copy of $var, leaving $var intact
}
$var = new Test('original');
doSmth($var);
var_dump($var);

Related

PHP - Call object methods dynamically via variables

I am trying to unit-test some of my code and it would be easier to just call my setters dynamically based on some variables. Unfortunately my approach does not work as expected and I couldn't find more information regarding on how to do that.
I have one variable which always is a string. It is used as property name and together with the "set" keyword it should result in "setSomething" or "setSomethingElse".
I already tried
$obj->set{$property}($value);
// or
$obj->set$property($value);
But those do not seem to work.
Maybe someone of you pro's know the right approach ;)!
You need to make the entire method name a variable, or enclose the whole name in {} e.g.
class test {
public $Something;
public $SomethingElse;
function setSomething($value) {
$this->Something = $value;
}
function setSomethingElse($value) {
$this->SomethingElse = $value;
}
}
$property = "Something";
$t = new test;
$setter = "set$property";
$t->$setter(4);
echo $t->Something;
$property = "SomethingElse";
$t->{"set$property"}(8);
echo $t->SomethingElse;
Output
4
8
Demo on 3v4l.org

Convert static method to lambda in PHP

I want to get static method from class and copy it to variable.
This is non-working example illustrating my question:
class foo
{
public static function bar($argument){ return 2*$argument; }
}
$class = new ReflectionClass('foo');
// here is no ReflectionMethod::getClosure() method in reality
$lambda = $class->getMethod('bar')->getClosure();
echo $lambda(3);
So my question: is this possible by any normal way? I find only one way for now. I can parse source file, get method source from it and convert it using create_function() but it's too perverse.
Just wrap it with closure.
$lamda = function($argument){return foo::bar($argument);};
Or you can try to use something like this
function staticMethodToClosure($class, $method) {
return function($argument)use($class, $method){return $class::$method($argument);};
}
An array in the format array($className, $methodName) is invokable as a static method call so this may work for you.
class foo
{
public static function bar($argument){ return 2*$argument; }
public static function getStaticFunction($arg){
return array("foo", $arg);
}
}
$a = foo::getStaticFunction("bar");
echo $a(5); // echos 10

How to Pass a function to a class in php

I have a class that generates data based on a few things. I would like to format that data from the outside. So I am trying to pass a function into the class so that it would format that data. I have looked at many examples, but it seems this is unique.
Can anybody give an idea of how to do this? The following code gives an error.
<?php
class someClass {
var $outsideFunc; // placeholder for function to be defined from outside
var $somevar='Me'; // generated text
function echoarg($abc){
$outsideFunc=$this->outsideFunc; // bring the outside function in
call_user_func($outsideFunc,$abc); // execute outside function on text
echo $abc;
}
}
function outsidefunc($param){ // define custom function
$param='I am '.$param;
}
$someClass=new someClass();
$someClass -> outsideFunc = 'outsideFunc'; // send custom function into Class
$someClass -> echoarg($someClass->somevar);
$someClass -> outsidefunc = 'outsidefunc';
In PHP, function names are not case sensitive, yet object property names are. You need $someClass->outsideFunc, not $someClass->outsidefunc.
Note that good OOP design practice calls for the use of getter and setter methods rather than just accessing properties directly from outside code. Also note that PHP 5.3 introduced support for anonymous functions.
Yeah. You are right. Now there is no error. But it does not work either.
By default, PHP does not pass arguments by reference; outsidefunc() does not actually do anything useful. If you want it to set $param in the caller to something else, and do not want to just return the new value, you could change the function signature to look like this:
function outsidefunc(&$param) {
You would also need to change the way you call the function, as call_user_func() does not allow you to pass arguments by reference. Either of these ways should work:
$outsideFunc($abc);
call_user_func_array($outsideFunc, array(&$abc));
Why not pass your function as an argument?
<?php
class someClass {
public $somevar="Me";
public function echoarg($abc,$cb=null) {
if( $cb) $cb($abc);
echo $abc;
}
}
$someClass = new someClass();
$someClass->echoarg($someClass->somevar,function(&$a) {$a = "I am ".$a;});
i am not sure what exactly you are looking for, but what i get is, you want to pass object in a function which can be acheive by
Type Hinting in PHP.
class MyClass {
public $var = 'Hello World';
}
function myFunction(MyClass $foo) {
echo $foo->var;
}
$myclass = new MyClass;
myFunction($myclass);
OP, perhaps closures are what you're looking for?
It doesn't do EXACTLY what you're looking for (actually add function to class), but can be added to a class variable and executed like any normal anonymous function.
$myClass->addFunc(function($arg) { return 'test: ' . $arg });
$myClass->execFunc(0);
class myClass {
protected $funcs;
public function addFunc(closure $func) {
$this->funcs[] = $func;
}
public function execFunc($index) { $this->funcs[$index](); } // obviously, do some checking here first.
}

how do I condense this statement?

I have the following function:
<?php
class Test{
function myFunction(){
return array('first','second','third');
}
}
?>
And I can print out the elements of the array:
$var=new Test();
$varr=$var->myFunction();
print($varr[1]);
Is there a way to condense this statement so I don't have to assign $var->myFunction() to a second variable (in this case $varr)?
PHP does not support this very well (as of PHP 5.3) as Tim Cooper already highlighted. So you need to think twice if you really need to have this compacted.
You can do things quite dynamically e.g. by return an ArrayObject instead of an array:
class Test
{
function myFunction()
{
return new ArrayObject(array('first','second','third'), 3);
}
}
$var = new Test();
print($var->myFunction()->{1});
Which will decorate the array data with some additional methods and ways of accessing. Another way would be for functions w/o parameter to fool the PHP parser and offer a property instead of a function dynamically:
class Test
{
function myFunction()
{
return array('first','second','third');
}
public function __get($name)
{
return $this->$name();
}
}
$var = new Test();
print($var->myFunction[1]);
But I don't know if this is really useful in an application.
So check your motivation why you want to compact the code and then decide on your own.
In PHP 5.4 you'll be able to do:
$varr=$var->myFunction()[1];
Until then, using list might help out:
list(,$varr) = $var->myFunction();
Another solution is to modify your method to accept an optional index of the item to return:
function myFunction($index = null){
$arr = array('first','second','third');
return $index == null ? $arr : $arr[$index];
}
$varr = $var->myFunction(1);

Copy a function on the fly PHP

I'm working on a project which requires a function to be copied & executed on the fly and variables in it needs to be replaced on the fly too.
A simple example will be like this:
function myfunction()
{
$abc = $_SESSION['abc'];
return $abc;
}
I want to be able to call myfunction1() which does NOT physically exist in the code but does exactly the samething as the one above except it now take values from my custom variable so it'll look like this:
function myfunction1()
{
$abc = $myCustomVariable;
return $abc;
}
Any one help pls?
The more you describe how convoluted your function is, the more it sounds like a perfect candidate for an object with injected dependencies.
For instance, you could have (just going to describe the basic interfaces here):
class myClass
{
public function __construct($provider DataProvider)
{
$this->provider = $provider;
}
// Please name this something better
public function doStufferer()
{
if ($this->provider->hasParam('foo'))
{
return $this->provider->getParam('foo');
}
}
}
class SessionProvider implements DataProvider
{
// Session specific stuff
}
class OtherProvider implements DataProvider
{
// Other provider stuff
}
interface DataProvider
{
public function getParam($key);
public function hasParam($key);
public function setParam($key, $value);
}
You can then use it like this:
$dataProcessor = new myClass(new SessionProvider);
// OR $dataProcessor = new myClass(new OtherProvider);
$dataProcessor->doStufferer();
Please take a look at PHP Classes and Objects and the other related topics.
This is what parameters are for, I think your looking todo something like this:
$myCustomVariable = 'Some value';
function myfunction($var=$_SESSION['abc'])
{
$abc = $var;
return $abc;
}
myfunction(); //returns $_SESSION['abc']
myfunction($myCustomVariable); //returns "Some Value"
The direct answer is eval which I do not recommend.
You could have your function accept a parameter, like this.
function myfunction1($some_var)
{
$abc = $some_var;
return $abc;
}
// call it like...
myfunction1($myCustomVariable);
If you need to access a variable, but the name is generated by dynamic code, you can use $GLOBALS.
function myfunction1($name_of_var)
{
$abc = $GLOBALS[$name_of_var];
return $abc;
}
// call it like...
$myCustomVariable = 'a value'
myfunction1('myCustom' + 'Variable');

Categories