I have a variable $className which is name of declared class in php and I want
create an object of this class
lunch a static method of this class
$obj = new $className();
$var = $className::method();
1:
$obj = new $className
2:
$className::someMethod($parameter)
There's also the Reflection API. E.g.:
<?php
$rc = new ReflectionClass('A');
// question 1) create an instance of A
$someArgs = array(1,2,3);
$obj = $rc->newInstanceArgs($someArgs);
// question 2) invoke static method of class A
$rm = $rc->getMethod('foo');
if ( !$rm->isStatic() ) {
echo 'not a static method';
}
else {
$rm->invokeArgs(null, $someArgs);
}
class A {
public function __construct($a, $b, $c) { echo "__construct($a,$b,$c)\n";}
public static function foo($a, $b, $c) { echo "foo($a,$b,$c)\n";}
}
Related
I try to create object in PHP class, but i get some interesting errors in IDE, like unexpected ( token etc. Here is my code:
class A {
public $a = 1;
}
class B {
$aa = new A();
}
Where is the problem?
In PHP, you can only assign "fixed" values to properties in the class definition.
class A {
public $a = 3; // will work
public $b = "hello"; // will work
public $c = foo(); // won't work
public $d = new Foo(); // won't work
}
If you want to do so, you can use the __construct() method which will be called every time a new instance is created or any other method that you call.
class B {
public $aa; // define visibility of $aa
function __construct() {
$this->aa = new A();
}
}
You need to make a constructor on class A
class A {
function __construct() {
$this->a = 1;
}
public function returnA() {
return $this->a;
}
}
$aa = new A();
echo $aa->returnA();
Try to create a constructor in class A and see if it works:
class A {
public $a;
function __construct()
{
$this->$a = 1;
}
}
class B {
$aa = new A();
}
Question:
How to push $param from load() to $data property in class A?
Therefor I can use get_class_vars get_object_vars to load them.
Each time I use load function, it will add $param to $data property.
Example:
<?php
class Test {
public function testing($str) { echo $str; }
}
class A {
public $data = array();
public function load($param) {
array_push($this->data, $param); // not adding $param to $data property
return $param = new $param;
}
}
class B {
public $a;
public function __construct() {
$this->a = new A();
var_dump(get_object_vars($this->a)); // showing empty $data property
}
}
// Usage
$b = new B();
$test = $b->a->load('test');
$test->testing('hello');
Edit:
used get_object_vars($this->a)
get_class_vars only shows default public variables. Use get_object_vars($this->a) instead; this should work.
i have something like this:
class foo
{
//code
}
$var = new foo();
$var->newVariable = 1; // create foo->newVariable
$var->otherVariable = "hello, im a variable"; //create foo->otherVariable
i can get in class foo a list of all variables defined outside by user (newVariable, otherVariable,etc)? Like this:
class foo
{
public function getUserDefined()
{
// code
}
}
$var = new foo();
$var->newVariable = 1; // create foo->newVariable
$var->otherVariable = "hello, im a variable"; //create foo->otherVariable
var_dump($var->getUserDefined()); // returns array ("newVariable","otherVariable");
Thanks!.
Yes, using get_object_vars() and get_class_vars():
class A {
var $hello = 'world';
}
$a = new A();
$a->another = 'variable';
echo var_dump(get_object_vars($a));
echo '<hr />';
// Then, you can strip off default properties using get_class_vars('A');
$b = get_object_vars($a);
$c = get_class_vars('A');
foreach ($b as $key => $value) {
if (!array_key_exists($key,$c)) echo $key . ' => ' . $value . '<br />';
}
What is your goal? Imo it's not very good practice (unless you really know what you are doing). Maybe it's good idea consider create some class property like "$parameters" and then create setter and getter for this and use it in this way:
class foo {
private $variables;
public function addVariable($key, $value) {
$this->variables[$key] = $value;
}
public function getVariable($key) {
return $this->variables[$key];
}
public function hasVariable($key) {
return isset($this->variables[$key]);
}
(...)
}
$var = new foo();
$var->addVariable('newVariable', 1);
$var->addVariable('otherVariable', "hello, im a variable");
And then you can use it whatever you want, for example get defined variable:
$var->getVariable('otherVariable');
To check if some var is already defined:
$var->hasVariable('someVariable')
get_class_vars() http://php.net/manual/en/function.get-class-vars.php
You question is not clear though.
$var->newVariable = 1;
there are two possible contex of above expression
1) you are accessing class public variables.
like
class foo
{
public $foo;
public function method()
{
//code
}
}
$obj_foo = new foo();
$obj_foo->foo = 'class variable';
OR
2) you are defining class variable runtime using _get and _set
class foo
{
public $foo;
public $array = array();
public function method()
{
//code
}
public function __get()
{
//some code
}
public function __set()
{
// some code
}
}
$obj_foo = new foo();
$obj_foo->bar= 'define class variable outside the class';
so in which context your question is talking about?
I have the following three classes:
class a
{ public $test; }
class b extends a { }
class c extends a
{
function return_instance_of_b() { }
}
As you can see, both classes b and c derive from a. In the return_instance_of_b() function in c, I want to return an instance of the class b. Basically return new b(); with one additional restriction:
I need the data from the base class (a) to be copied into the instance of b that is returned. How would I go about doing that? Perhaps some variant of the clone keyword?
You can use the get_class_vars function to retrieve the names of the variables you want to copy, and just loop to copy them.
The variables that are defined are protected so they are visible to get_class_vars in its scope (since c extends a), but not directly accessible outside the class. You can change them to public, but private will hide those variables from get_class_vars.
<?php
class a
{
protected $var1;
protected $var2;
}
class b extends a
{
}
class c extends a
{
function __construct()
{
$this->var1 = "Test";
$this->var2 = "Data";
}
function return_instance_of_b()
{
$b = new b();
// Note: get_class_vars is scope-dependant - It will not return variables not visible in the current scope
foreach( get_class_vars( 'a') as $name => $value) {
$b->$name = $this->$name;
}
return $b;
}
}
$c = new c();
$b = $c->return_instance_of_b();
var_dump( $b); // $b->var1 = "Test", $b->var2 = "Data
I believe you can achieve this with some reflection. Not very pretty code, I'm sure there is a much more succinct method to achieve this but here you go.
class a
{
public $foo;
public $bar;
function set($key, $value) {
$this->$key = $value;
}
function get($key) {
return $this->$key;
}
}
class b extends a
{
function hello() {
printf('%s | %s', $this->foo, $this->bar);
}
}
class c extends a
{
public $ignored;
function return_instance_of_b() {
$b = new b();
$reflection = new ReflectionClass($this);
$parent = $reflection->getParentClass();
foreach($parent->getProperties() as $property) {
$key = $property->getName();
$value = $property->getValue($this);
$b->$key = $value;
}
return $b;
}
}
$c = new c();
$c->set('foo', 'bar');
$c->set('bar', 'bar2');
$c->set('ignored', 'should be!');
$b = $c->return_instance_of_b();
$b->hello();
// outputs bar | bar2
Additionally you could use nickb's answer but instead of hard coding the class you could use get_parent_class
function return_instance_of_b()
{
$b = new b();
foreach(get_class_vars(get_parent_class(__CLASS__)) as $name => $value) {
$b->$name = $this->$name;
}
return $b;
}
Can we dynamically create and initialize an object in PHP?
This is the normal code:
class MyClass{
var $var1 = null;
var $var2 = null;
.
.
public function __construct($args){
foreach($args as $key => $value)
$this->$key = $value;
}
}
---------------------
$args = ($_SERVER['REQUEST_METHOD'] == "POST") ? $_POST : $_REQUEST;
$obj = new MyClass($args);
The above code works fine. Please note that the names of REQUEST parameters are accurately mapped with the members of class MyClass.
But can we do something like this:
$class = "MyClass";
$obj = new $class;
If we can do like this, then can we initialize $obj by using $args.
According to this post, $obj = $class should work. But it does not work for me. I tried get_class_vars($obj). It threw an exception.
Thanks
It's more a comment, but I leave it here more prominently:
$class = "MyClass";
$obj = new $class($args);
This does work. See newDocs.
You have to overload some other magic methods:
__get (a method that gets called when you call object member)
__set (a method that gets called when you want to set object member)
__isset
__unset
Please see this codepad to see your code rewritten to work with what you want:
<?php
class MyClass{
var $properties = array();
public function __construct($args){
$this->properties = $args;
}
public function __get($name) {
echo "Getting '$name'\n";
if (array_key_exists($name, $this->properties)) {
return $this->properties[$name];
}
return null;
}
}
$args = array("key1" => "value1", "key2" => "value2");
$class = "MyClass";
$obj = new $class($args);
echo "key1:". $obj->key1;
?>
You can use Reflection to instanciate an object with parameters.
<?php
class Foo {
protected $_foo;
protected $_bar;
public function __construct($foo, $bar)
{
$this->_foo = $foo;
$this->_bar = $bar;
}
public function run()
{
echo $this->_foo . ' ' . $this->_bar . PHP_EOL;
}
}
$objectClass = 'Foo';
$args = array('Hello', 'World');
$objectReflection = new ReflectionClass($objectClass);
$object = $objectReflection->newInstanceArgs($args);
$object->run();
See Reflection on php manual.