How can I access to class variable from outside without creating new instance in PHP ? Something like this:
class foo
{
public $bar;
}
echo foo::$bar;
Is it possible or I must create method that will print or return this value and use it or create new instance ( $a = new foo; echo $a->$bar ) ?
EDIT: I don't want to create constant but classic variable that will be changed later.
make this variable static to access it with out class object.
If you wanted to change static variable value by method then you need to use static method
you can try like this:
class foo
{
public static $bar ="google";
public static function changeVal($val){
self::$bar=$val;
}
}
foo::changeVal("changed :)");
echo foo::$bar;
Output : changed :)
Demo : https://eval.in/107138
You also can changed it like this without static method:
foo::$bar = "changed";
demo : https://eval.in/107139
like this:
class foo
{
public static $bar ="google";
}
echo foo::$bar;
Output: google
demo: https://eval.in/107126
IF it makes sense to use a static variable:
class foo{
public static $bar = 'example';
}
Which could be accessed like so:
echo foo::$bar;
If the value will never change during runtime, then you probably want a class constant (http://www.php.net/oop5.constants)
class foo {
const bar = 'abc';
}
...otherwise you want a public static variable (http://www.php.net/manual/en/language.oop5.static.php)
class foo {
public static $bar = 'abc';
}
...either way, access it like this
echo foo::bar;
You can access the class variable without creating instances only when the variable is markesd as static:
class foo
{
public static $bar;
}
This is how you use a class variable:
// with instantiation
class foo {
// initialize on declare
public $bar = 1;
// or initialize in __construct()
public function __construct(){
$this->bar = 1;
}
}
$foo = new foo();
var_dump($foo->bar);
// static way
class static_foo {
public static $bar = 1;
}
var_dump(static_foo::$bar);
And this is how you instantiate a class from a random class name string variable.
$foo = new foo();
$random_class_name = $foo->bar;
try {
// following line throws if class is not found
$rc = new \ReflectionClass($random_class_name);
$obj = $rc->newInstance();
// can be used with dynamic arguments
// $obj = $rc->newInstance(...);
// $obj = $rc->newInstanceArgs(array(...));
} catch(\Exception $Ex){
$obj = null;
}
if($obj){
// you have a dynamic object
}
What's your actual question?
Related
In PHP, is it possible to access the static properties of an object that is itself a property of another object, using similar syntax below:
<?php
class Foo
{
public $bar;
function __construct()
{
$this->bar = new Bar();
}
}
class Bar
{
const TEST = 123;
function __construct() {}
}
$bar = new Bar();
$foo = new Foo();
echo Bar::TEST; // ok
echo $bar::TEST; // ok
echo $foo->bar::TEST; // error
?>
Assign the property to a variable.
$foo = new Foo();
$bar = $foo->bar;
echo $bar::TEST; // that's good.
more tricky, but you can use ReflectionClass
echo (new ReflectionClass(get_class($foo->bar)))->getconstant("TEST");
You might have better luck using Late Static Binding instead of inheritance on that property. So it would be something like this (changed to an example from the above PHP manual page):
<?php
class A
{
public static function who()
{
echo __CLASS__;
}
public static function test()
{
static ::who();
// Here comes Late Static Bindings
}
}
class B extends A
{
public static function who()
{
echo __CLASS__;
}
}
B::test();
?>
Here's another thread that might be relevant or helpful: PHP Inheritance and Static Methods and Properties
I would like to ask, if there is a way, to use variables in a class, that were declared out of it.
Example:
$foo = 'bar';
class foobar{
function example(){
echo "foo{$foo}";
}
}
$foobar = new foobar;
$foobar->example();
This code produces a notice: Notice: Undefined variable: foo
Is there a way to make it work? Or is there some work-around?
You could give this argument to your class with a constructor
class foobar{
private $foo;
public function __construct($name) {
$this->foo = $name;
}
}
and then use it.
Or what PeeHaa means, you could change your method to
function example($param){
echo "foo{$param}";
}
and call it like this
$foobar->example($foo);
Use a construct to import it or use the global keyword. You could do something like this:
$var = 'value';
class foobar {
private $classVar;
function __construct($param) {
$this->classVar = $param;
}
}
And initiate it like this:
$var = 'value';
$inst = new foobar($var);
Or you can use global variables (which I wouldn't recommend in this case) and do something like this:
$var = 'value';
class foobar {
global $var;
function show() {
echo $var;
}
}
UPDATE: To use a class within another class, it may be instantiated in the constructor if its instance is needed throughout implementation, or it may be instantiated only when needed.
To create a reference to another class inside the constructor, do something like this:
class class1 {
private $someVar;
function __construct() {
$this->someVar = 'success';
}
function doStuff() {
return $this->someVar;
}
}
class class2 {
private $ref;
private $val;
function __construct() {
$this->ref = new class1();
$this->val = $this->ref->doStuff();
// $this->val now holds the value 'success'
}
}
$inst = new class2(); // upon calling this, the $val variable holds the value 'success'
Or you can call it only when needed, like so:
class class1 {
private $someVar;
function __construct() {
$this->someVar = 'success';
}
function doStuff() {
return $this->someVar;
}
}
class class2 {
private $ref;
private $val;
function __construct() {
// do something
}
function assign() {
$this->ref = new class1();
$this->val = $this->ref->doStuff();
// $this->val now holds the value 'success'
}
}
$inst = new class2(); // the $val variable holds no value yet
$inst->assign(); // now $val holds 'success';
Hope that helps you.
Yes add
class foobar{
function example(){
global $foo;
echo "foo{$foo}";
}
}
** putting it in another class is better though, or passing it to the method you're using is better too **
I know I can reference a class' property using a variable as follows:
$field_name = 'first_name';
$myobject->$field_name // references $myobject->first_name
Is there a way I can reference a class property using another class' property? For example,
$myobject->{$model->field_name} // Does not work
This works for me:
class Foo {
public $bar = 'baz';
}
class Bar {
private $baz = 'Hello, World!';
public function __construct() {
$foo = new Foo;
echo $this->{$foo->bar};
}
}
new Bar;
It prints:
Hello, World!
$field_name = $model->field_name
$myobject->$fieldname
I can't seem to be able to override protected static variables. It's rather annoying, given that you cannot override any private variable as well. Howcan I fix that? (Have to support PHP 5.2)
<?
class Foo{
protected static $stuff = 'Foo';
public function showStuff(){
echo self::$stuff . PHP_EOL;
}
}
class Bar extends Foo{
protected static $stuff = 'Bar';
}
$f = new Foo();
$b = new Bar();
$f->showStuff(); // Output: Foo
$b->showStuff(); // Output: Foo
?>
You need to use late static bindings, a feature introduced in PHP 5.3. In your class Foo, self refers to the Foo class. You want to refer to the class where the call originated. You need to use the keyword static:
<?
class Foo{
protected static $stuff = 'Foo';
public function showStuff(){
echo static::$stuff . PHP_EOL; // <-- this line
}
}
class Bar extends Foo{
protected static $stuff = 'Bar';
}
$f = new Foo();
$b = new Bar();
$f->showStuff(); // Output: Foo
$b->showStuff(); // Output: Bar
?>
You can override them, but you cannot get the value from the parent class. Well, this is wat PHP calls overriding, while it actually reintroduces the variable and tries to hide the parent variable. That's why this won't work the way you want.
Since you're not on 5.3 yet, I think the best solution is to use (and override) a static function too. If you don't need to modify the value, you can just make the class override the function to let it return a different constant value per class. If you do need the variable, you can reintroduce both the variable and the function in each class.
class x
{
static $a = '1';
static function geta()
{
return self::$a;
}
}
class y extends x
{
static $a = '2';
static function geta()
{
return self::$a;
}
}
echo x::geta();
echo y::geta();
It is dirty, but it solves the problem until you can use the neater static:: way of PHP 5.3.
There is a better solution. You can use get_called_class() to find the current context and use that to access statics.
eg.
class Foo {
protected static $table = "foo";
static function getTable() {
$class = get_called_class();
return $class::$table;
}
}
class Bar extends Foo {
protected static $table = "bar";
}
echo Foo::getTable()."<br />\n";
echo Bar::getTable()."<br />\n";
You will get output as follows:
foo<br />
bar<br />
That will work in any PHP 5 version
Actually you can override them :)
You just can't use them in parent class, as they are static. Late static binding fixes it.
I saw this example from php.net:
<?php
class MyClass {
const MY_CONST = "yonder";
public function __construct() {
$c = get_class( $this );
echo $c::MY_CONST;
}
}
class ChildClass extends MyClass {
const MY_CONST = "bar";
}
$x = new ChildClass(); // prints 'bar'
$y = new MyClass(); // prints 'yonder'
?>
But $c::MY_CONST is only recognized in version 5.3.0 or later. The class I'm writing may be distributed a lot.
Basically, I have defined a constant in ChildClass and one of the functions in MyClass (father class) needs to use the constant. Any idea?
How about using static::MY_CONST?
Since php 5.3:
Use static::MY_CONST
More details on static
In this case the keyword static is a reference to the actually called class.
This illustrates the difference between static $var, static::$var and self::$var:
class Base {
const VALUE = 'base';
static function testSelf() {
// Output is always 'base', because `self::` is always class Base
return self::VALUE;
}
static function testStatic() {
// Output is variable: `static::` is a reference to the called class.
return static::VALUE;
}
}
class Child extends Base {
const VALUE = 'child';
}
echo Base::testStatic(); // output: base
echo Base::testSelf(); // output: base
echo Child::testStatic(); // output: child
echo Child::testSelf(); // output: base
Also note that the keyword static has 2 quite different meanings:
class StaticDemo {
static function demo() {
// Type 1: `static` defines a static variable.
static $Var = 'bar';
// Type 2: `static::` is a reference to the called class.
return static::VALUE;
}
}
Instead of
$c = get_class( $this );
echo $c::MY_CONST;
Do this
$c = get_class( $this );
echo constant($c . '::MY_CONST');
I couldn't get it to work with const as it prints "yonderyonder" (that's the thing about constants, they don't change), but it works fine with var:
<?php
class MyClass {
var $MY_CONST = "yonder";
public function __construct() {
echo $this->MY_CONST;
}
}
class ChildClass extends MyClass {
var $MY_CONST = "bar";
}
$x = new ChildClass(); // prints 'bar'
$y = new MyClass(); // prints 'yonder'
?>
If you need to access constants, properties, methods of classes or objects you can use reflection, it provides much more details about structure of the object.
example:
class MainClass
{
const name = 'Primary';
public $foo = 'Foo Variable';
}
class ExtendedClass extends MainClass
{
const name = 'Extended';
}
/**
* From Class Name
*/
//get reflection of main class
$mainReflection = new ReflectionClass('MainClass');
if($mainReflection->hasConstant('name'))
var_dump($mainReflection->getConstant('name'));//Primary
//get reflection of extended class
$extendedReflection = new ReflectionClass('ExtendedClass');
if($extendedReflection->hasConstant('name'))
var_dump($extendedReflection->getConstant('name'));//Extended
/**
* From Objects
*/
$main = new MainClass();
$extended = new ExtendedClass();
//get reflection of main class
$mainReflection = new ReflectionObject($main);
if($mainReflection->hasConstant('name'))
var_dump($mainReflection->getConstant('name'));//Primary
//get reflection of extended class
$extendedReflection = new ReflectionObject($extended);
if($extendedReflection->hasConstant('name'))
var_dump($extendedReflection->getConstant('name'));//Extended