I have an interface in PHP
interface IDummy{
public function DoSomething();
}
I have another class that implements this interface.
class Dummy implements IDummy{
public function DoSomething(){
}
How can I type cast the Dummy Object to IDummy in PHP, so that I can call it as
$dum = new Dummy();
$instance = (IDummy)$dum;
$instance->DoSomething();
Can I do this in PHP?
Thanks and Regards
Abishek R Srikaanth
The cast is completely unnecessary. It will simply work.
And the Dummy objects will be considered an instance of IDummy if you ever check it with one of the various type hinting functions.
This works... no casting needed:
interface I {
public function foo();
};
class A implements I {
public function foo() { }
}
function test(I $obj) {
$obj->foo();
}
$a = new A();
test($a);
If class Dummy already implements interface IDummy, there's no need to cast $dum to IDummy - just call method DoSomething().
interface IDummy
{
public function doSomething();
}
class Dummy implements IDummy
{
public function doSomething()
{
echo 'exists!';
return;
}
}
$dummy = new Dummy();
$dummy->doSomething(); // exists!
The code should simply be:
$class = new ClassName;
$class->yourMethod();
As #konforce pointed out, not typecasting is required. You might want to check PHP method_exists() function http://php.net/manual/en/function.method-exists.php.
Well, it could be fun, see java functionality regarding this issue.
interface I {
public function foo();
};
class A implements I {
public function foo() { echo 'This should be accessible.'; }
public function baz() { echo 'This should not be available.'; }
}
$dum = new A();
$instance = (I) $dum;
$instance->foo(); // this should work
$instance->baz() // should not work
Note: This code throws error. It seems that you can not cast interface like that. In java is possible.
If you know the class name from the configuration or something else that you don't know, I think this should work:
$classname = 'Dummy';
$reflectionClass = new \ReflectionClass($classname);
$instance = $reflectionClass->newInstance();
// $dum = new $className; //you can do this as well I guess
if( $instance instanceof IDummy){
$instance->DoSomething();
}
Related
For example:
$m = new mysqli('host', 'user', 'pass', 'db');
$q = $m->query('SELECT stuff FROM table');
while ($row = $q->fetch_assoc()) {
// do stuff
}
How does the query method end up having its own distinct "sub-methods" like fetch_assoc()?
How can I replicate this behaviour using OOP?
EDIT ... would this be considered correct and / or good practice?
class MyClass {
function myMethod() {
return new AnotherClass();
}
}
class AnotherClass {
function __construct() {
$this->stuff = 'stuff';
}
}
Then, I can do:
$obj = new MyClass;
$stuff_getter = $obj->myMethod();
echo $stuff_getter->stuff;
It's a little bit opinion based what you are asking, but because i think a lot of people are strugling with this i will provide some general information about this case.
First of all, you can't say if this is a good practice or not. It depends on the intention and the context. See this code:
class MyClass {
function myMethod() {
return new AnotherClass();
}
}
Is it ok? Yes it's ok what you are doing, but note that you have a strong dependency here. If you ever want for some reason to have different implementations
of AnotherClass you need to change the code.
You can prevent this by using dependency injection. Implement an interface in AnotherClass and inject it into MyClass.
When you have another implementation of AnotherClass you can just pass it like the 'old' version.
How to implement this is also depends on what the intention of your code is but i will provide a basic example of your code.
class MyClass {
private $aClass = null;
function __construct($aClass)
{
$this->aClass = $aClass;
}
function myMethod() {
return new $this->aClass();
}
}
interface AnInterface
{
}
class AnotherClass implements AnInterface {
function __construct() {
$this->stuff = 'stuff';
}
}
$obj = new MyClass(new AnotherClass());
$stuff_getter = $obj->myMethod();
echo $stuff_getter->stuff;
Now using this i can just create another implementation of AnotherClass and pass it to MyClass like i always did. Instead of your scenario where i need to add another function. E.g:
class AnotherClass2 implements AnInterface {
function __construct() {
$this->stuff = 'another stuff';
}
}
$obj = new MyClass(new AnotherClass2());
$stuff_getter = $obj->myMethod();
echo $stuff_getter->stuff;
The second thing i notice is you aren't defining variables. I think it's a little opinion based, but i'm strongly against public variables (which in your case is by default).
Create a variable and assign that variable in your constructor. Create getters and setters (if you are lazy you can create magic getters en setters (see here). You would get something like this:
class AnotherClass implements AnInterface {
private $stuff;
function __construct() {
$this->stuff = 'stuff';
}
public function getStuff()
{
return $this->stuff;
}
}
$obj = new MyClass(new AnotherClass());
$stuff_getter = $obj->myMethod();
echo $stuff_getter->getStuff();
I hope this makes some clearness about your construction, although this might not be fully answering your question.
Two notes on this.
The interface is not always necessary in PHP, but it sure is the best practice.
Instead of implementing an interface you could also use an inheritance stucture if you have a lot of duplication and ofcourse you are allowed to use inheritance (is it an is-a relation?).
Your final code could be (as interface example) something like this:
class MyClass {
private $aClass = null;
function __construct($aClass)
{
$this->aClass = $aClass;
}
function myMethod() {
return new $this->aClass();
}
}
interface AnInterface
{
public function getStuff();
}
class AnotherClass implements AnInterface {
private $stuff;
function __construct() {
$this->stuff = 'stuff';
}
public function getStuff()
{
return $this->stuff;
}
}
class AnotherClass2 implements AnInterface {
private $stuff;
function __construct() {
$this->stuff = 'another stuff';
}
public function getStuff()
{
return $this->stuff;
}
}
$obj = new MyClass(new AnotherClass());
$stuff_getter = $obj->myMethod();
echo $stuff_getter->getStuff();
$obj = new MyClass(new AnotherClass2());
$stuff_getter = $obj->myMethod();
echo $stuff_getter->getStuff();
I am new to php and trying to call a function in another class.
How do I call function1 and function2 in class xyz???
class abc {
private $lmn = "lmn";
private $say1;
private static $static;
private function __construct(){
$say1 = print $this->lmn;
}
public static function1(){
$static = "YEAAHHHH";
}
public function function2(){
return $this->say1;
}
file 2:
require 'abc.php';
class xyz {
/**
* $e = new xyz();
*
*/
$e = xyz:: function1();// error
$d = xyz:: function 2(); //error
}
Also under what circumstance I should use
$obj = new class();
$obj->functionname();
and
$obj = class::functionname();
You have 2 different types of methods here, static and non-static.
To call the static (function1())
You don't need to instantiate the class, as it's static.
class zyx {
public function foo() {
return abc::function1();
}
}
To call the non-static (function2())
You need to instantiate the class, as it's not static.
class zyx {
public function foo() {
$abc = new abc();
return $abc->function2();
}
}
You would call function1 like:
abc::function1();
It is a method in abc not xyz.
function2() you would only call if you had an instance of abc because it is an instance method and not a static method. I.e.
$abc = new abc();
$abc->function2();
Static functions are intended to be called on classes, instance methods (i.e. function2() are intended to be called on instances of classes. I would recommend reading http://php.net/manual/en/oop5.intro.php.
Static functions can be called without instantiating your class...
$myClass::function1();
Non-static functions need to be instantiated first:
$myClass = new abc();
$myClass->function2();
So in your example:
require 'abc.php';
class xyz {
public function CallFunc1()
{
abc::function1();
}
public function CallFunc2()
{
$myClass = new abc();
$myClass->function2();
}
}
require 'abc.php';
class xyz {
public function static(){
return abc:: function1();// this is a static function
}
public function nonstatic(){
$e = new abc();
return $e->function2();
}
}
First of all, you can't have a space between function and 2():
$d = xyz::function2(); //correct
$d = xyz::function 2(); //very incorrect
I was going to have a second of all, but #hd beat me to it.
I think you have messed up with the code. I can share something with something that I found very helpful as an answer for your second question. Spend a bit time reading this. This is very basic, simple and well guided.
http://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762
I'm new to programming. I have this going on:
I have Class A, which have many functions. One of those functions is functionX.
In functionX I need to make a call to functionY which belongs to another class: Class B.
So how do I acces to functionY from inside functionX?
I use Codeigniter.
Thanks in advance.
Try and experiment with this.
class ClassA {
public function functionX() {
$classB = new ClassB();
echo $classB->functionY();
}
}
class ClassB {
public function functionY() {
return "Stahp, no more OO, stahp!";
}
}
Class function? A static method?
If you have an instance (public) method, you just call $classB->functionY().
If you have a static method, you would call ClassB::functionY();
So:
class ClassA {
public function functionX(){
$classB = new ClassB();
// echo 'foo';
echo $classB->functionY();
// echo 'bar';
echo ClassB::functionYStatic();
}
}
class ClassB {
public $someVar;
public static $someVar2 = 'bar';
function __construct(){
$this->someVar = 'foo';
}
public function functionY(){
return $this->someVar;
}
public static function functionYStatic(){
return self::$someVar2;
}
}
Well that depends. If that function is a static function or not.
First off you must include the file with the class...
include_once('file_with_myclass.php');
If it is static you can call it like this:
ClassName::myFunction()
If it is not, then you create an instance of the class and then call the function on that instance.
$obj = new ClassName();
$obj->myFunction();
As you can guess the function being static means you can call it without the need of creating an instance. That is useful for example if you have a class Math and want to define a function that takes to arguments to calculate the sum of them. It wouldn't really be useful to create an instance of Math to do that, so you can declare as static and use it that way.
Here's a link to the docs with further info
http://www.php.net/manual/en/keyword.class.php
If functionY is static you can call ClassB::functionY(). Else you must create instance of Class B first. Like:
$instance = ClassB;
$instance->functionY();
But maybe you mean something else?
Looks like one of your class has a dependency to another one:
<?php
class A
{
public function x()
{
echo 'hello world';
}
}
class B
{
private $a;
public function __construct(A $a)
{
$this->a = $a;
}
public function y()
{
$this->a->x();
}
}
$a = new A();
$b = new B($a);
$b->y();
Depending how your code looks like, if it makes sense, you can inject class A into y()
public function y(A $a)
{
// your code with $a
}
I have an idea of using this syntax in php. It illustrates that there are different fallback ways to create an object
function __construct() {
if(some_case())
$this = method1();
else
$this = method2();
}
Is this a nightmare? Or it works?
Or it works?
It doesn't work. You can't unset or fundamentally alter the object that is being created in the constructor. You can also not set a return value. All you can do is set the object's properties.
One way to get around this is having a separate "factory" class or function, that checks the condition and returns a new instance of the correct object like so:
function factory() {
if(some_case())
return new class1();
else
return new class2();
}
See also:
Breaking the constructor
PHP constructor to return a NULL
Why not to do something more common like:
function __construct() {
if(some_case())
$this->construct1();
else
$this->construct2();
}
You can just create class methods method1 and method2 and just write
function __construct() {
if(some_case())
$this->method1();
else
$this->method2();
}
You can make factory method.
Example:
class A {}
class B {}
class C {
function static getObject() {
if(some_case())
return new A();
else
return new B();
}
}
$ob = C::getObject();
It sounds a little bit like the Singleton class pattern.
See #Ivan's reply among others for the correct syntax for what it looks like you're trying to do.
However, there are is another alternative - use a static method as an alternative constructor:
class myclass {
function __construct() { /* normal setup stuff here */}
public static function AlternativeConstructor() {
$obj = new myclass; //this will run the normal __construct() code
$obj->somevar = 54; //special case in this constructor.
return $obj;
}
}
...
//this is how you would use the alternative constructor.
$myobject = myclass::AlternativeConstructor();
(note: you definitely can't use $this in a static method)
If you want to share some functions, do some like
class base{
'your class'
}
class A extends base{
'your class'
}
class B extends base{
'your class'
}
And call like
if(some_case())
$obj = new A();
else
$obj = new B();
Is it possible to set the parent of the class? I.e. an instance of the parent class gets instantiated during runtime and then a child class instance extending a certain parent instance gets created. For example:
class A {
var $test = 'default';
}
class B extends A {
public function __contsruct(A $a) {
parent = $a; //does not work
}
}
$a = new A();
$a->test = 'changed';
$b = new B($a);
$b->test == 'changed'; //should be true
I know that I could just $b = new B(); $b->test = 'changed', but that's not what I'm asking about.
A simple way to accomplish this is like so:
class Foo
{
function __construct() {
$this->hello = "Hello";
}
public function sayHello() {
echo $this->hello."!";
}
}
class Bar
{
function __construct(&$foo) {
$this->foo = $foo;
}
public function sayHelloAgain() {
echo $this->foo->sayHello()." Again!";
}
}
$foo = new Foo();
echo $foo->sayHello(); //outputs "Hello!"
$bar = new Bar($foo);
echo $bar->sayHelloAgain(); //outputs "Hello! Again!"
What you've asked for is not possible in base PHP. There are a few ways to do similar things.
You could use the highly experimental runkit extension. The runkit_class_emancipate and runkit_class_adopt functions should work. However, they operate on entire classes, not instances of a class. This probably limits their usefulness for your application.
If you're trying to emulate the expandable class features of other languages, like Ruby and Perl, runkit_method_add and related functions might be more suitable. Again, however, it still operates on entire classes.
The normally accepted "PHP way" to do things like this is via __call. In fact, with anonymous functions in 5.3, you can do something like...
class Bar {
public function say($thing) {
echo "Bar::say says: $thing\n";
}
}
class Foo extends Bar {
private $extensions = array();
public function addExtension($func_name, $func) {
$this->extensions[ $func_name ] = $func;
}
public function __call($func_name, $arguments) {
array_unshift($arguments, $this);
if(array_key_exists($func_name, $this->extensions))
call_user_func_array($this->extensions[ $func_name ], $arguments);
}
}
$f = new Foo();
$anon = function($obj, $string){ $obj->say($string); };
$f->addExtension('example', $anon);
$f->example("Hello, world!");
You'll note in __call and that in creating the anonymous function that the first argument becomes the instance. That's because PHP 5.3's implementation of anonymous functions can't reference $this. That also means that they can't reference protected or private members of the class. This can be corrected by cloning the instance and using Reflection to expose the protected and private members. See this comment on the anonymous function manual page for an example implementation.
Because of limitations of PHP, you can't directly assign an anonymous function to a property and call it. This example will not work:
class WillNotWork {
public $fatal_error;
}
$broken = new WillNotWork();
$anon = function($arg) { echo "I'm about to create a {$arg} error!"; };
$broken->fatal_error = $anon;
$broken->fatal_error("fatal");
// Fatal error: Call to undefined method WillNotWork::fatal_error()
No, because $a is a separate instance than $b.