Consider this sample code
<?php
class MyAwesomeClass {
public $myawesomeproperty = 'test';
public function __construct() {
$self = new stdClass();
$self->myawesomeproperty = "hello guys!";
}
}
$test_obj = new MyAwesomeClass();
echo '<pre>';
var_export( $test_obj );
echo '</pre>';
?>
It's supposed to set "myawesomeproperty" to a new string so var_export shows "hello guys!" in the output.
What I'm actually getting is
MyAwesomeClass::__set_state(array(
'myawesomeproperty' => 'test',
))
Apparently the construct function does not save anything to actual object.
Why is this happening? What am I missing?
You're setting the property of a local variable called $self. If you want to change the object's property, use $this instead:
<?php
class MyAwesomeClass {
public $myawesomeproperty = 'test';
public function __construct() {
$this->myawesomeproperty = "hello guys!";
}
}
$test_obj = new MyAwesomeClass();
echo '<pre>';
var_export( $test_obj );
echo '</pre>';
?>
You are creating a different object ($self) inside the constructor. You aren't doing anything with it, so the object is removed from memory when php leaves the function scope.
To overwrite a property of the object attached to the current function scope, use $this->myawesomeproperty="Hello Guys";
Related
How can I create a property from a given argument inside a object's method?
class Foo{
public function createProperty($var_name, $val){
// here how can I create a property named "$var_name"
// that takes $val as value?
}
}
And I want to be able to access the property like:
$object = new Foo();
$object->createProperty('hello', 'Hiiiiiiiiiiiiiiii');
echo $object->hello;
Also is it possible that I could make the property public/protected/private ? I know that in this case it should be public, but I may want to add some magik methods to get protected properties and stuff :)
I think I found a solution:
protected $user_properties = array();
public function createProperty($var_name, $val){
$this->user_properties[$var_name] = $val;
}
public function __get($name){
if(isset($this->user_properties[$name])
return $this->user_properties[$name];
}
do you think it's a good idea?
There are two methods to doing it.
One, you can directly create property dynamically from outside the class:
class Foo{
}
$foo = new Foo();
$foo->hello = 'Something';
Or if you wish to create property through your createProperty method:
class Foo{
public function createProperty($name, $value){
$this->{$name} = $value;
}
}
$foo = new Foo();
$foo->createProperty('hello', 'something');
The following example is for those who do not want to declare an entire class.
$test = (object) [];
$prop = 'hello';
$test->{$prop} = 'Hiiiiiiiiiiiiiiii';
echo $test->hello; // prints Hiiiiiiiiiiiiiiii
Property overloading is very slow. If you can, try to avoid it. Also important is to implement the other two magic methods:
__isset();
__unset();
If you don't want to find some common mistakes later on when using these object "attributes"
Here are some examples:
http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members
EDITED after Alex comment:
You can check yourself the differences in time between both solutions (change $REPEAT_PLEASE)
<?php
$REPEAT_PLEASE=500000;
class a {}
$time = time();
$a = new a();
for($i=0;$i<$REPEAT_PLEASE;$i++)
{
$a->data = 'hi';
$a->data = 'bye'.$a->data;
}
echo '"NORMAL" TIME: '.(time()-$time)."\n";
class b
{
function __set($name,$value)
{
$this->d[$name] = $value;
}
function __get($name)
{
return $this->d[$name];
}
}
$time=time();
$a = new b();
for($i=0;$i<$REPEAT_PLEASE;$i++)
{
$a->data = 'hi';
//echo $a->data;
$a->data = 'bye'.$a->data;
}
echo "TIME OVERLOADING: ".(time()-$time)."\n";
Use the syntax: $object->{$property}
where $property is a string variable and
$object can be this if it is inside the class or any instance object
Live example: http://sandbox.onlinephpfunctions.com/code/108f0ca2bef5cf4af8225d6a6ff11dfd0741757f
class Test{
public function createProperty($propertyName, $propertyValue){
$this->{$propertyName} = $propertyValue;
}
}
$test = new Test();
$test->createProperty('property1', '50');
echo $test->property1;
Result: 50
Is it possible to print a variable which has the value inside the function but it's called from outside the function to be print in object oriented programming in PHP
Let's explain by example
My class looks like as:
class my {
public $a;
public function myFunc(){
$name = "fahad";
echo $this->a;
}
}
It should print the value of $name when the function is call, as I am trying:
$class = new my();
$class->a = '$name';
$class->myFunc();
But it did't work and print the result as:
$name
I want it should print the value of variable $name which is inside the function
How it can be possible?
Thank You.
You can use variable variables to do this, but it's usually considered bad practice.
class my {
public $a;
public function myFunc(){
$name = "fahad";
echo ${$this->a};
}
}
$class = new my();
$class->a = 'name';
$class->myFunc();
Output:
fahad
Inside your function, you can make a check:
public function myFunc(){
if($this->a == '$name'){
$name = 'fahad';
echo $name;
}else echo $this->a;
}
Is it possible to get the line and file where a object is created?
For example.
I know the print PHP error outputs where a error occurred and at which line. Is it possible to use that mechanism?
Sending the file to the object is easy. I can just use basename(__FILE__) as an argument. But I would prefer if the object arguments can remain empty. Like this:
Foo.php
<?php
class Foo {
public $line = null;
public function __construct(){
$this->line = where_object_is_assigned
}
}
?>
Index.php
<?php
$object = new Foo();
echo $object->line // Output Index.php line 3
?>
Is there a way for the object to access this data without sending it?
Thanks in advance
I solved it by using the function debug_backtrace();
<?php
class Foo {
public $line = null;
public function __construct(){
$bt = debug_backtrace();
$caller = array_shift($bt); // Get first array
$this->line = $caller["line"];
}
}
?>
Index.php
<?php
$object = new Foo();
echo $object->line // Output: 3
?>
The function must be used in __construct() else it won't work.
Read more here: http://php.net/manual/en/function.debug-backtrace.php
This will output on which line-number the object is created
Class
class Foo {
public $line = NULL;
public function __construct($line){
$this->line = $line;
}
}
Index.php
<?php
$object = new Foo(__LINE__); //Will output 1
echo $object->line;
PHP provides a large number of predefined constants to any script which it runs. Within this you can simply find the predefined constant named as LINE
__LINE__ The current line number of the file.
So you need to simply use the predefined constant within your code like as
<?php
class Foo {
public $line = __LINE__;
}
$object = new Foo();
echo $object->line;
?>
I'm quite inexperienced with OOP PHP but here's my question...let's say I have this class with one property:
class myClass {
public $property = array();
public function getProperty() {
return $this->property;
}
}
How would it be possible to change the value of $property without altering the class itself in any way, or by instantiating an object out of it, then changing its property. Is there any other way of doing it? Using scope resolution?
Hope that makes sense, any help would be much appreciated.
What you want is a static member
class MyClass {
public static $MyStaticMember = 0;
public function echoStaticMember() {
echo MyClass::$MyStaticMember;
//note you can use self instead of the class name when inside the class
echo self::$MyStaticMember;
}
public function incrementStaticMember() {
self::$MyStaticMember++;
}
}
then you access it like
MyClass::$MyStaticMember = "Some value"; //Note you use the $ with the variable name
Now any instances and everything will see the same value for whatever the static member is set to so take for instance the following
function SomeMethodInAFarFarAwayScript() {
echo MyClass::$MyStaticMember;
}
...
MyClass::$MyStaticMember++; //$MyStaticMember now is: 1
$firstClassInstance = new MyClass();
echo MyClass::$MyStaticMember; //will echo: 1
$firstClassInstance->echoStaticMember(); //will echo: 1
$secondInstance = new MyClass();
$secondInstance->incrementStaticMember(); // $MyStaticMember will now be: 2
echo MyClass::$MyStaticMember; //will echo: 2
$firstClassInstance->echoStaticMember(); //will echo: 2
$secondInstance->echoStaticMember(); //will echo: 2
SomeMethodInAFarFarAwayScript(); //will echo: 2
PHPFiddle
I hope this is what you are looking for
<?php
class myClass {
public $property = array();
public function getProperty() {
print_r($this->property);
}
}
$a = new myClass();
$x = array(10,20);
$a->property=$x; //Setting the value of $x array to $property var on public class
$a->getProperty(); // Prints the array 10,20
EDIT :
As others said , yes you need the variable to be declared as static (if you want to modify the variable without creating new instance of the class or extending it)
<?php
class MyClass {
public static $var = 'A Parent Val';
public function dispData()
{
echo $this->var;
}
}
echo MyClass::$var;//A Parent Val
MyClass::$var="Replaced new var";
echo MyClass::$var;//Replacced new var
?>
I want to pull all info about a file from a files table, but that table's structure might change.
So, I'd like to pull all the field names from the table and use them to generate the class variables that contain the information, then store the selected data to them.
Is this possible?
Yes you can, see php overloading.
http://php.net/manual/en/language.oop5.overloading.php
Quick Example: ( Not this isn't great usage )
<?php
class MyClass{
var $my_vars;
function __set($key,$value){
$this->my_vars[$key] = $value;
}
function __get($key){
return $this->my_vars[$key];
}
}
$x = new MyClass();
$x->test = 10;
echo $x->test;
?>
Sample
<?php
class TestClass
{
public $Property1;
public function Method1()
{
$this->Property1 = '1';
$this->Property2 = '2';
}
}
$t = new TestClass();
$t->Method1();
print( '<pre>' );
print_r( $t );
print( '</pre>' );
?>
Output
TestClass Object
(
[Property1] => 1
[Property2] => 2
)
As you can see, a property that wasn't defined was created just by assigning to it using a reference to $this. So yes, you can define class variable from within a class method.