get the name of the object calling one of its methods - php

is it possible to get the name of the object which calls one of its methods.
scenario:
I have class A. I instantiate 2 objects of that class. If one object calls a method, is it possible to retrieve the name of the object which called it?
EDIT:
class Property() {
public function __call($name, $atts) {
if ($name === 'foo') {
//I want to differ Between Color and Position
}
}
}
$Color = new Property();
$Position = new Property();
$Color->foo();
$Position->foo();

Add a name element to your object:
class ObJA {
$this->name;
function __construct($name){
$this->name = $name;
}
function getName(){ return $this->name; }
}
On object create:
$a = new ObJA('a');
$b = new ObJA('is b');
echo $a->getName(); //`a`
echo $b->getName(); //`is b`

You can always use get_class(), but the name is not going to change simply by creating two or more instances of the object. Neal's solution will work but it doesn't actually change the name of the class, and begs the question: Why do you need it?

Related

Get class prop name in php

I'm not good at php OOP.
class Example{
public $name;
public $age;
}
$example = new Example();
I would like to get the property name as string, like-
echo get_property_name($example->name); //should echo 'name'
//OR,
echo $example->name->toString(); //should echo 'name'
Please note that, I don't want to write the property name in a string or variable like-
$property = $class->getProperty('name');
I don't want to get the value of property, I want to get the name of the property as a string.
Is it possible in php?
You can build a helper function with get_object_vars(). Because you already know the var-name, the function only checks, if this exists in the object and returns the var as string:
function get_property_name($oObject, $sString) {
$aObjectVars = get_object_vars($oObject);
if( isset($aObjectVars[$sString]) ) {
return $sString;
}
return false; // object var not exists
}
In PHP you can introspect a class, function, or... with ReflectionClass:
<?php
class Example
{
public $name;
public $age;
}
$example = new Example();
$ref = new ReflectionClass($example);
$props = $ref->getProperties();
foreach($props as $prop) {
var_dump($prop->name);
}
The output:
string(4) "name"
string(3) "age"
one other option would be a trait with following methods.
public function toArray(): array
{
return (array) $this;
}
public function properties(): array
{
return array_keys($this->toArray());
}
We do not know your use case. If you write a DTO, Reflection might be your desired way. If you write a model with some extra sugar, you could store all attributes in an array to load and edit them. Probably two arrays so you could compare edited and loaded values. with __isset, __get, __set you can always preload attributes.

What those $variable->$variable in OOP php do?

I am following a tutorial and have come across the following code in defining a user class:
class User {
public $id;
public $username;
public $password;
public $first_name;
public $last_name;
public static function instantiate($record) {
$object = new self;
foreach ($record as $attribute => $value){
if ($object->has_attribute($attribute)){
$object->$attribute = $value;
}
}
return $object;
}
private function has_attribute($attribute) {
$object_vars = get_object_vars($this);
return array_key_exists($attribute, $object_vars);
}
}
My question is: What does the "$object->$attribute = $value;" do exactly ?
I am just starting in OOP php and I am really confuse of what that bit of code is downing.
Thanks a lot.
Pretty basic question : it is assigning the value $value to the attribute $attribute of the object $object.
In other words, it is copying the value of the variable $value to the attribute of the object $object.
It's an assignment statement for an attribute of the PHP class. Let's use a less ambiguous example. We will create a small person class that holds a first name and a last name.
class Person
{
//Class attributes
public $fisrtName;
public $lastName;
}
Using the above example, if you wanted to set those attributes, you would do the following:
//Instantiate a new person
$myPerson = new Person();
//Assign values to the person object
$myPerson->firstName = "John";
$myPerson->lastName = "Smith";
Alternately, if you wanted to assign the value myPerson object's firstName field to a different variable, you could do the following:
$personsName = $myPerson->firstName;
All this is doing is internally creating a new instance of it's creating a new instance of it's self for a form of recursion or other functionality,
so calling:
$object->$attribute
is essentially, from what I can see. Will create a new instance then depending on the contents of $attribute return a value or call a method

Storing php object's property in another object as a reference

Is it possible to store a reference to an object's property (class member variable which holds a scalar data such as string or integer) within an object of a different class?
I am trying to have the following two echo statements produce identical results.
<?php
$x = new Type;
$x->name = 'abcd';
echo "x.name=" . $x->name . '<br/>';
echo "x.obj.name=" . $x->obj->value . '<br/>';
class Type
{
public $obj; //Instance of Property (Property class defined below)
public $name;
function __construct()
{
$this->obj = new Property($this->name);
}
}
class Property
{
public $value;
function __construct($v)
{
$this->value = $v;
}
}
$this->obj = new Property($this->name);
Is called at the time of object creation. Which is executed before the assignment.
i.e.
When you call $x = new Type;
The constructor is called and you try to copy 'name' which is empty by then
May be what you want it following, rather than passing the value, pass $this and keep the referance.
<?php
class Type
{
public $obj; //Instance of Property (Property class defined below)
public $name;
function __construct()
{
$this->obj = new Property($this);
}
}
class Property
{
public $value;
function __construct($ref)
{
$this->value = $ref;
}
}
$x = new Type;
$x->name = 'abcd';
echo "x.name=" . $x->name . '<br/>';
echo "x.obj.name=" . $x->obj->value->name . '<br/>';
You can pass the name value inside the constructor.
$x = new Type('abcd');
Without doing that, your constructor will not know what $this->name is yet. So we use it in the constructor and set the classes property before using it.
function __construct($p_name){
$this->name = $p_name;
$this->obj = new Property($this->name);
}
You could just as easily set the value after calling the constructor and then initialize the reference afterwards -
class Type {
public $obj;
public $name;
function setProperty(){
$this->obj = new Property($this->name);
}
}
$x = new Type;
$x->name = 'abcd';
$x->setProperty();
echo "x.name=" . $x->name;
echo "x.obj.name=" . $x->obj->value;
This is an old question but just to add to this.
You can have an object with methods and properties inside of another object..
Example
$obj1 = new class1();
$obj2 = new class2($obj1); // you just grabbed $obj1 and stuck it inside $obj2
Now you can use the stored object's methods like so:
$obj2->obj1->method_from_obj1();
or access the stored object's properties like so:
$obj2->obj1->property_of_obj1;
This is SUPER convenient if you instantiated an object of some API and want to use the API methods inside of your own object.
While at the time of answering this question is 9+ years old, I've encountered a similar issue today and found a way to do what's requested.
In short: you should use references. Here's a a working example (PHP 8):
<?php
class Source
{
public int $counter = 10;
}
class Consumer
{
public int $value = 0;
public function __construct(int &$value)
{
$this->value = &$value;
}
}
$source = new Source();
// Pass property of Source instance to the consumer.
$consumer = new Consumer($source->counter);
assert($consumer->value === 10);
// Changing value in the Source instance.
$source->counter = 15;
// ... and value in the consumer updated as well.
assert($consumer->value === 15);
exit;
So, the answer is yes, it is possible.

Why is my PHP class acting static?

New to PHP.
I have created a simple class:
class User
{
private $name;
private $password;
private $email;
public function getName()
{
return $this->name;
}
public function setName($value)
{
$this->name = $value;
}
public function setPassword($value)
{
$this->password = $value;
}
public function setEmail($value)
{
$this->email = $value;
}
public function getEmail()
{
return $this->email;
}
}
I created 2 instances of this class and stored the first instance into an array. I am then checking to see if the second instance exists in the array (the one I did not add to the array). For some reason in_array() always returns '1' or true.
It turns out that the array now somehow contains the second user object that I did not explicitly add to the array. As if the properties of User are behaving like static class members. What am I missing?
$user = new User();
$user::setName('Nick');
$user::setEmail('bbbb#gmail.com');
$user::setPassword('bbbbb');
$somethingelse = new User();
$somethingelse::setName('Mindy');
$somethingelse::setEmail('a#gmail.com');
$somethingelse::setPassword('aaaa');
$arr = array('users'=>$user); //add first object to array
echo in_array($somethingelse,$arr); //check if second object is in array
echo $arr['users']::getName(); //Prints mindy
}
Because you're using the namespace resolution operator ::, rather than the instance dereferencing operator ->. The first invokes the method on the class, the second on an instance. If you turn on E_STRICT error reporting (which you should!), you'll see a bunch of warnings about calling instance methods statically.
To fix this, use $user->setName('Nick'); (with similar changes elsewhere).
use
->
instead of
::
In short, it’s used to access Static or Constant members of a class.
it would result in
$user = new User();
$user->setName('Nick');
$user->setEmail('bbbb#gmail.com');
$user->setPassword('bbbbb');
$somethingelse = new User();
$somethingelse->setName('Mindy');
$somethingelse->setEmail('a#gmail.com');
$somethingelse->setPassword('aaaa');
$arr = array('users'=>$user); //add first object to array
echo in_array($somethingelse,$arr); //check if second object is in array
echo $arr['users']->getName(); //Prints mindy

Why does Static member variable inherits the value when instantiatiing object number of times in PHP?

i was testing the Static Keyword on how exactly does it work and i came across this which i don't understand what is happening.
Consider two Classes ClassNameA & ClassNameB with the following codes.
ClassNameA without Static Keyword
class ClassNameA
{
private $name;
public function __construct($value) {
if($value != '') {
$this->name = $value;
}
$this->getValue();
}
public function getValue() {
echo $this->name;
}
}
ClassNameB with Static Keyword
class ClassNameB
{
private static $name;
public function __construct($value) {
if($value != '') {
self::$name = $value;
}
$this->getValue();
}
public function getValue() {
echo self::$name;
}
}
When i instantiate the object multiple times using ClassNameA
$a = new ClassNameA(12);
echo '<br/>';
$a = new ClassNameA(23);
echo '<br/>';
$a = new ClassNameA(''); //Argument given is Empty here
it outputs the folowing
12
23
And now when i instantiate the object multiple times using ClassNameB
$a = new ClassNameB(12);
echo '<br/>';
$a = new ClassNameB(23);
echo '<br/>';
$a = new ClassNameB(''); //Argument given is Empty here
It outputs the following
12
23
23
Note the extra value 23 it is taking even if the Argument Passed is Empty. Is this a bug? or am i missing something?
This is the nature of static property. The static property is a kind of property of class not the property of object.
When you passed the blank, according to the condition the value of static property will not get updated and last value is still there in the static property.
Since the static property is not bounded with any of the object hence it is available without a need any object.
$a = new ClassNameB(12); //static property is set to 12
echo '<br/>';
$a = new ClassNameB(23); //static property is update to 23
echo '<br/>';
$a = new ClassNameB(''); //static property is not updated here it is still 23
EDIT
You can understand like this:-
if($value != '') {
$this->name = $value; //
}
What the code above is doing it is setting the property value for current object (object which is initializing right now).
So when you wrote
$a = new ClassNameA(12);
What it is doing it is setting the name property to 12 for object a;
$a = new ClassNameA(23);
What it is doing it is setting the name property to 23 for object a;
But when the property is static that is for the whole class not for any object.
so when you wrote
if($value != '') {
self::$name = $value;
}
The code above is setting the static property value. Note that here you wrote self instead of $this which make it use for this class only and not for any of the object.
I tried to explain it better but don't know how it is explaining for you.
A static member is a single instance across the entire application, not once per object. For example
class Example {
static public $var;
static public MyFunction() {
echo "MyFunction\n";
}
}
Example::$var = 123;
echo Example::$var;
Example::MyFunction();
Note how we did not need to create an instance of "Example", essentially its name-spacing the variable to the class. This would be invalid:
$example = new Example();
echo $example->var;
$example->MyFunction();
You can also reference it inside the class as
self::$var
self::MyFunction();
Which makes it safe to rename the class later if you need to. A static function can not access non static member or method though.

Categories