As far I know the is operator in ActionScript does the following: (rectify me, if I am wrong)
Tests whether a variable or expression is compatible with a given data type.
Examines the inheritance hierarchy
Can be used to check whether an object is an instance of a particular class or a child (or grandchild, great grandchild, great great grandchild, and so on) of a particular class.
Check whether an object is an instance of a class that implements a particular interface
Now I want to know what in PHP is/are similar to Actionscript 's "is" operator?
In PHP you have construction instanceof:
$a instanceof MyClass
The "is" operator is used for comparing/testing data type membership (type checking). In php, you can used instanceof to check the specific type of the object.
$obj = new A();
if ($obj instanceof A) {
...
}
ActionScript's is operator is equivalent to PHP's instanceof operator
<?php
class Person {}
$p1 = new Person();
$p2 = new Person();
echo ($p1 instanceof $p2)?"True":"False"; //o/p: True bcz both $p1 & $p2 are the instances of same class
echo ($p1 instanceof Person)?"True":"False";//True , checking through class name
interface LoyalCustomer{}
class Customer extends Person implements LoyalCustomer {}
$c1 = new Customer();
echo ($c1 instanceof $p1)?"True":"False";//True
class RegularCustomer extends Customer{}
$rc1 = new RegularCustomer();
echo ($rc1 instanceof $p1)?"True":"False";//True
echo ($rc1 instanceof $c1)?"True":"False";//True
echo ($rc1 instanceof RegularCustomer)?"True":"False";//True
echo ($rc1 instanceof Customer)?"True":"False";//True
echo ($rc1 instanceof Person)?"True":"False";//True
echo ($p1 instanceof LoyalCustomer)?"True":"False";//False
echo ($c1 instanceof LoyalCustomer)?"True":"False";//True
echo ($rc1 instanceof LoyalCustomer)?"True":"False";//True
echo ($p1 instanceof $rc1)?"True":"False";//False
?>
Related
This question comes form the following link
http://php.net/manual/en/language.oop5.basic.php
Specifically, Example #5 Creating new objects
$obj1 = new Test();
$obj2 = new $obj1;
var_dump($obj1 !== $obj2); //bool(true)
I can't figure out why it is okay or logical to use the new operator on $obj1 to create $obj2 when $obj1 is clearly just an object, not a class?
I have been trying to find reference on this topic, but could not find one.
Thanks
I have no idea why they added a possibility to create a new object with an instance of the class but the instance is used as a class in this case. You even can pass constructor arguments. Try this code:
class Waat {
public $message;
public function __construct($message )
{
$this->message = $message;
}
}
$w1 = new Waat('hello');
$w2 = new $w1('world');
echo $w1->message . ' ' . $w2->message;
It outputs:
hello world
I was looking at OOP Basics and saw a code like this (simplified it a bit)
You can see this class and the output
class Test{}
$a = new Test();
$b = new $a;
var_dump($b == $a); // true
What I don't understand is the $b = new $a but $a is already an object, so how/why does this work? If I do vardump $a the output is:
object(Test)#1 (0) {
}
So, how can that variable work with new keyword. I thought we could only use new with a class that is defined already, or with a string that points to a class ex:
$var = 'Test';
new $var; // ok
but in this case, $var is a string, not an another object.
It is a shortcut for creating new object. Before PHP 5.3.0 you have to do this:
$class = get_class($instance);
$newInstance = new $class;
As of PHP 5.3.0 you can do the same thing with this:
$newInstance = new $instance;
Very useful, in my opinion, because it eliminates the need for a temporary variable.
To clarify, this creates new object.
It is not cloning.
In other words, __construct() will be called instead of __clone().
I have a class (lets call it TestClassA) in which the constructor looks something like this
public function __constructor(SomeInterface $some, AnotherInterface $another, $additionalArgs = null)
{
// Rest of code
}
The value of $additionalArgs can come from any of four unique classes. Each of these classes will add unique query arguments to the class above according to the user's condition set. Lets name these classes
TestB
TestC
TestD
TestE
I'm not sure if interface injection will be my best solution here, as, once a condition is set, it will most probably never change again, and only one option can be set at any given time. For example, if the user has decided to use TestC class, the probability that he will change to either of the other three remaining classes is almost zero. So, if I'm correct, if I use interface injection (like in the example below) and add all four classes, I will instantiate 3 classes unnecessarily as they will in most probability never get used
public function __constructor(
SomeInterface $some,
AnotherInterface $another,
TestBInterface $testB,
TestCInterface $testC,
TestDInterface $testD,
TestEInterface $testE
) {
// Rest of code
}
What I thought of was to create my TestClassA with a property of $additionalArgs, creating a new instance of the required class, lets say TestC and then passing that to the $additionalArgs, which I then use in a method to get the required values.
Example
$a = new SomeClass;
$b = new AnotherClass;
$c = new TestC;
$d = new TestClassA($a, $b, $c->someMethod());
My question is, how do I make sure that the value passed to $additionalArgs is a valid instance of one of the four classes that should be passed to this parameter. I have already tried to verify this using instanceof in my method, in this example someMethod() , but the condition fails
Any suggestions on how to address this problem, and still "comply" with basic OOP principles?
Currently you're passing in the result of a method, you can't test that to see what class it came from so instanceof won't work. What you need to do is pass in the object, test that and then call the method. Try this:
class TestClassA() {
$foo;
$bar;
$testB;
$testC;
$testD;
$testE;
public function __constructor(Foo $foo, Bar $bar, $test = null)
{
$this->foo = $foo;
$this->bar = $bar;
if ( ! is_null($test))
{
if ($test instanceof TestClassB)
{
$this->testB = $test->someMethod();
}
elseif ($test instanceof TestClassC)
{
$this->testC = $test->someMethod();
}
elseif ($test instanceof TestClassD)
{
$this->testD = $test->someMethod();
}
elseif ($test instanceof TestClassE)
{
$this->testE = $test->someMethod();
}
// Optional else to cover an invalid value in $test
else
{
throw new Exception('Invalid value in $test');
}
}
// Rest of code
}
}
$a = new Foo;
$b = new Bar;
$c = new TestClassC;
$d = new TestClassA($a, $b, $c);
I might have missed something in is_a() and instanceof but is there a way to make this string version work?
$myclass = 'MyClass';
if ($myclass instanceof MyClass) {
echo 'Yes';
} else {
echo 'No';
}
This works fine as expected and prints Yes:
$myclass = new MyClass();
if ($myclass instanceof MyClass) {
echo 'Yes';
else {
echo 'No';
}
Question:
Check if variable which stores name of a class is an instanceof a class
My answer:
If a variable stores a name of a class it cannot be instance of that class because it's a string!
What you might wanted:
Check if variable stores a name of existing class
Solution to that:
if (class_exists($myclass)) { ... }
I want to execute some functions if entity is member of few classes but not some.
There is a function called instanceof.
But is there something like
if ($entity !instanceof [User,Order,Product])
Give them a common interface and then
if (!$entity instanceof ShopEntity)
or stay with
if (!$entity instanceof User && !$entity instanceof Product && !$entity instanceof Order)
I would avoid creating arbitrary functions just to save some characters at a single place. On the other side if you need it "too often", you may have a design flaw? (In the meaning of "too much edge cases" or such)
PHP manual says: http://php.net/manual/en/language.operators.type.php
!($a instanceof stdClass)
This is just a logical and "grammatically" correct written syntax.
!$class instanceof someClass
The suggested syntax above, though, is tricky because we are not specifying which exactly is the scope of the negation: the variable itself or the whole construct of $class instanceof someclass. We will only have to rely on the operator precendence here [Edited, thanks to #Kolyunya].
PHP Operator Precedence
instanceof operator is just before negation then this expression:
!$class instanceof someClass
is just right in PHP and this do that you expect.
This function should do it:
function isInstanceOf($object, Array $classnames) {
foreach($classnames as $classname) {
if($object instanceof $classname){
return true;
}
}
return false;
}
So your code is
if (!isInstanceOf($entity, array('User','Order','Product')));
function check($object) {
$deciedClasses = [
'UserNameSpace\User',
'OrderNameSpace\Order',
'ProductNameSpace\Product',
];
return (!in_array(get_class($object), $allowedClasses));
}
Or you can try these
$cls = [GlobalNameSpace::class,\GlobalNameSpaceWithSlash::class,\Non\Global\Namespace::class];
if(!in_array(get_class($instance), $cls)){
//do anything
}