Will isset() trigger __get and why? - php

class a {
function __get($property){...}
}
$obj = new a();
var_dump(isset($obj->newproperty));
Seems the answer is nope but why?

Because it checks __isset rather than retrieving it using __get.
It is a much better option to call __isset, as there is no standard on what is empty. Maybe in the context of the class null is an acceptable value. You could also have a class that if the member didn't exist, it returned a new empty object, which would break isset($myObj->item) as in that case it would always return true.

It just isn't; you can use __isset instead. This is laid out here.

No, __get should not be triggered when you're trying to determine whether a property is set : testing if a property is set is not the same thing as trying to get its value.
Using isset triggers the __isset magic method.
See :
isset
and Overloading

The magic function __get is only called when you try to access a property that doesn't exist. Checking whether a property exists is not the same as retrieving it.

Class A{
public function __get($key){
...
}
public function __set($key,$name){
...
}
public function __unset($key){
...
}
public function __isset($key){
...
}
}
$obj = new A();
$get = $obj->newproperty;//$obj->__get("newproperty")
$obj->newproperty = "X";//$obj->__set("newproperty","X")
$bool = isset($obj->newproperty);//$obj->__isset("newproperty")
unset($obj->newproperty);//$obj->__unset("newproperty")

Related

php chain method return variable and method calls another method

I saw different articles about chain method, but I still don't understand the difference between "return $this" and "return $this->SomeVariable".I also want to know how a method call another method within and without the class too.
Could someone kindly explain it ?
thanks you!
My example, it echo "bca", but I dont get why "a" is the last to display...
class validation {
public function __construct($a) {
$this->a = $a;
}
public function one($a) {
echo $a = "b";
return $this;
}
public function two($a) {
echo $a = "c";
return $this->a;
}
}
$a = "a";
$NameErr = new validation($a);
echo $NameErr->one($a)->two($a);
It is returned from two($a) since it returns $this->a that is set in constructor as "a", and method one($a) returns instance of the object on which is then called function two.
$this refers to the object instance. So difference is that return $this->SomeVariable it just returns the variable.
Also just a nice coding tip. Declare $a in class as private variable like this:
class Validation
{
private $a;
}
First let me say
$this refers to the class you are in.
This way of coding is called fluent interface. return $this returns the current object,
$NameErr->one($a)->two($a);
is same as
$NameErr->one($a);
$NameErr->two($a);
And in this case
First the method one() is called,
thus the value b is printed and the object of the class is returned.
Now method two() is called,
the value c is echoed out and the property is returned, which is echoed out side the class.
ps: Declaring the variable $a as private would be a nice practice.

__get is not called if __set is not called, however code works?

Here is my code:
<?php
class SampleClass {
public function __get($name){
echo "get called";
echo $name;
}
public function __set($name, $value) {
echo "set called";
}
}
?>
And my index file:
$object = new SampleClass();
$object->color = "black";
echo $object->color;
If I run this code as it is, here is the output:
set calledget calledcolor
However if I comment out
public function __set($name, $value) {
echo "set called";
}
the part above (only this part), then the output will be:
black
So what happened here?
__get will only be called is no property exists. By removing __set, you create a property when setting, so instead of calling __get, php just returns the property.
A simple way to think about it is that __get and __set are error handlers - They kick in, when php can't otherwise honor your request.
This is an explanation of what is happening. In your first example. You never stored the value within the object, nor did a declared property exist. This, echo $object->color; never actually does anything as nothing is returned from __get.
In your second example, you assigned a value to a property in your object. Since you did not declare the property in your object, it gets created by default as public. Since its public, __get is never called when accessing it.

PHP - Overloaded class function

Helo everyone.
I have a class MyClass and a function escape() that can be called as a static class or as an instantiated Object.
MyClass::_escape('..... some string...');
or
$myclass->escape();
What I would like is not to have the underscore on the staic version and for both just have the same function definition. I trie to do.
class MyClass {
public $_string = "";
public function escape($string = null) {
if($string == null)
return new String(mysql_real_escape_string($this->_string));
else
return new String(mysql_real_escape_string($string));
}
}
but this function fails by the PHP parser. Is there a way of doing what I attempted to above??
So to summarise, I would like the static call to look like;
print Myclass::escape('some string');
and the instantiated call to look like;
print $myobject->escape(); //Which escapes the private variable _string
Hope this was clear.
regards
public function _escape($s){
return self::escape($s);
}
What you're trying to achieve won't work without at least some kind of error:
Example using static:
error_reporting(E_ALL ^ E_STRICT);
class MyClass
{
// note the *static* keyword
public static function escape($string = null) {
// $this is not defined, even if called as object-method
var_dump(isset($this));
}
}
$foo = new MyClass();
$foo->escape(); // => bool(false)
MyClass::escape(); // => bool(false)
So, if you remove the static keyword and try again, you'll get:
$foo->escape(); // => bool(true)
but also:
Strict Standards: Non-static method MyClass::escape() should
not be called statically ...
for
MyClass::escape(); // => bool(false)
There are no parse errors in the code you posted. In fact, it works just as you want it to work, as long as you never pass $string to the escape() method in an object context:
$foo = new MyClass();
$foo->_string = 'foo';
$foo->escape(); // This works.
MyClass::escape('bar'); // This works, too.
$foo->escape('baz'); // Don't do this. It'll escape $string instead of $this->_string.
You could resolve this issue by determining whether or not you're in a static context within the escape() method, instead of checking for the existence of $string.

__isset() magic function on the Object it self

I know you can do this
class Object
{
private $ar;
public function __isset($name)
{
return isset($this->ar[$name]);
}
}
which can then be used to do the following
$obj = new Object();
if (isset($obj->name)) { /* ... */ }
However is there a way to do this
$obj = new Object();
if (isset($obj)) { /* .... */ }
Where i can control the return of $obj status using the __isset() magic method on the object it self.
You could only define a new global function myIsset() or something like it to do this.
function myIsset($obj = NULL)
{
...
}
When checking the variable $obj with isset PHP doesn't interact with the object that might be referenced by the variable at all.
You cannot, because it would not make any sense (at least not in the way isset() is meant to be used). So isset($obj) is always true as long as it points to some object and not NULL/undefined.
Magic method __isset is not intended to be used that way.
According to PHP manual:
"__isset() is triggered by calling isset() or empty() on inaccessible properties."

PHP: How many of these lines don't work, static vs non-static access

http://codepad.viper-7.com/ezvlkQ
So, I'm trying to figure out:
...?php
$object = new A();
class A
{
static public $foo = 'bar';
function displayFoo()
{
echo $this->$foo;
}
}
A::displayFoo();
A->displayFoo();
?>
About this, how many errors can you find? Can you tell me what they are in real human terms? I can't really interpret what is and what is not okay from the validator that codepad uses...
I’ve updated your code here http://codepad.viper-7.com/UaUE4g
Error 1:
echo $this->$foo;
This should read:
echo self::$foo;
.. as it is static.
Error 2:
A::displayFoo();
The method is an instance method :: is used for access to static methods.
Error 3:
A->displayFoo();
This is an error because A is undefined and if it was it should have read $A. This would be okay:
$object->displayFoo();
.. as $object is an instance of class A.
Next step, consult the manual on the topic static.
Not sure where to start. Static methods belong to the class, normal methods belong to an object, an instantiation of that class. For example, you can have:
Class A {
static public $foo = 'WOOHOOO';
static function displayFoo() {
echo self::$foo;
}
}
echo A::displayFoo();
This works because you're calling the displayFoo method belonging to class A. Or you can do this:
Class A {
public $foo = "WOOHOO";
public function displayFoo() {
echo $this->foo;
}
}
$obj = new A();
$obj->displayFoo();
Now you're creating an object based on the class of A. That object can call its methods. But the object doesn't have static methods. If you were to declare the function static, it would not be available to $obj.
You can't do:
A->displayFoo()
at all, under any circumstances, ever. The -> operator assumes an object, and A can't be an object because its not a variable.
You can read up on static class members in the manual here:
http://php.net/static
Pay close attention to the examples.

Categories