Anyone know how to redeclare function?
For example:
class Name{}
//Code here
class Name{}
And the output is:
Cannot redeclare class
So I tried to name the class as a variable:
$foo = 'name';
class $foo{}
//Code
class $foo{}
Edit: I have a DataBase table and I am reading data from the table user 'while()' loop.
I have a class that uses the table and echo some information.
That is the reason.
And it's still not working...
Any suggestions?
If you want to have several classes with the same name, then you should be using namespaces.
Use PHP NameSpace
namespace A {
class Name {
function __toString() {
return __METHOD__;
}
}
}
namespace B {
class Name {
function __toString() {
return __METHOD__;
}
}
}
namespace C {
echo new \A\Name ,PHP_EOL;
echo new \B\Name ,PHP_EOL;
}
Output
A\Name::__toString
B\Name::__toString
Nope. PHP simply doesn't support runtime modification of an existing class
Why would you want to re-declare a class? when you ca reference to it at any point?
I think what you're looking for is to create a new instance of a class:
$foo = 'name';
$obj1 = new $foo();
//Code
$obj2 = new $foo();
You shouldn't have 2 or more classes with the same name. This is not working. How should the interpreter know which class is the correct class?
Change the name of the second class and extend them if you need it.
Edit: Use Namespaces of you need the same classname or if you have an existing class.
If you need two instances of a class you can just initialise it twice as two different varialbes;
class Foo{}
$foo1 = new Foo;
$foo2 = new Foo;
Use PHP namespaces to declare classes with the same name but different purposes.
First of all: Do not do this.
That said, if you really need to "refedine" a class, you can use a wrapper class to do so
<?php
class foo { //Original definition here };
class bar {
var $baseobj;
function bar($some, $args) {
$this->baseobj=new $which($some, $args);
}
function someMethod() {
return $this->baseobj->someMthod();
}
//...
}
class baz {
function someMethod() {
return "This is the result";
}
//...
}
$obj=new bar($this, $that);
//$obj is now a wrapped foo object
echo $obj->someMethod(); //Will call into foo
$obj->baseobj=new baz($this, $that);
//$obj is now a wrapped baz object
echo $obj->someMethod(); //Will call into baz
?>
Again: Do not do this without a very, very good reason!
Disclaimer: This implementation is more than crude, it is only ment to transport the idea.
Related
I have a DB interface object, DBI, that requires authentication. I have an object, foo, that doesn't extend anything. I also have a class bar that extends the DBobject If I have an instance of foo that is a member of bar thus:
$b->$f=new foo;
How can I call somefunction() in $b from a function inside the foo class? I've tried making the somefunction() static, but I don't want the authentication info sprinkled throughout my code. And if I try having foo extend the DBI or bar classes, I wind up with an issue including the files and my foo __construct function fails because the bar class is not found. Is there another construct similar to extends/parent:: that I can use with objects that are just instances amongst each other?
The way that I've done this in the past, is create the Foo object within the Bar object within the __construct(). Then utilize the __call magic method to intercept the methods and see where it is. So the code could look something like this:
public function __call($sMethod, $aArgs) {
if(method_exists($this, $sMethod){
return call_user_func_array(array($this, $sMethod), $aArgs);
}
} elseif(method_exists($this->foo, $sMethod)) {
return call_user_func_array(array($this->foo, $sMethod), $aArgs);
}
}
public function __construct() {
$this->foo = new foo();
}
Then you can call the functions from either foo or bar, even though they are not extended. Just a though, maybe there is an easier way to do this.
** EDIT **
The benefit to this is you don't need to specify whether or not you are calling a method from foo or from bar, they will just "work".
** EDIT **
Based on the comments, you want to do this, correct? Because based on the code below, if you run it it works correctly.
class foobar {
public function test() {
echo 'This is a test';
}
}
class foo extends foobar {
}
class bar {
}
$bar = new bar();
$bar->foo = new foo();
$bar->foo->test();
or the alternative:
class foobar {
public function test() {
echo 'This is a test';
}
}
class foo extends foobar {
}
class bar {
public function testFooBar() {
$this->foo->test();
}
}
$bar = new bar();
$bar->foo = new foo();
$bar->testFooBar();
Both work at long as you know the property name you are setting for the object.
In addition to call_user_func and call_user_func_array, if you want to access methods and properties of the container object (not parent class), you need a reference to it. Here is a similar post.
Take the following example:
class A implements Serializable {
serialize() {}
}
class B extends A {
serialize() {}
}
Class A is a persistant but minimal class used on every page. class B is temporary admin only (used on a settings screen) class which populates members by reading files.
I need to serialize the object and store in the database twice, once for regular pages, and the second (with a limited life) for the admin page.
$instance = new B(); // and populate
$data = serialize( $instance );
This will always call the over-ridden method. Is there any way I could cast $instance to type A so that I can call on class A's serialize method?
It's possible by creating a closure, Looks following snippet for demonstration
<?php
interface Greeting
{
public function hello();
}
class A implements Greeting
{
public function hello()
{
echo "Say hello from A\n";
}
}
class B extends A
{
public function hello()
{
echo "Say hello from B\n";
}
}
$b = new B();
$closure = function() {
return parent::hello();
};
$closure = $closure->bindTo($b, 'B');
$closure(); // Say hello from A
$b->hello(); // Say hello from B
The answer is no, you cannot. The children redeclare the parent functionality of the method and completely override it. For this, static methods would be required.
class Second
{
// i've got to access to $variable from First instance from here
}
class First
{
public $variable;
public $SecondInstance;
public function __construct($variable)
{
$this->variable = $variable;
$this->SecondInstance = new Second();
}
}
$FirstObj = new First('example variable');
I need an equivalent for parent::$variable for objects.
Is there a possibility to do that in that way?
No, you cannot. The only way you can manage that, without extending First, is to pass "$this" to the constructor of Second:
$this->SecondInstance = new Second ($this);
Or, you can simply pass $variable to its constructor.
You mean like the parent function in PHP:
//You may find yourself writing code that refers to variables
//and functions in base classes. This is particularly true if
// your derived class is a refinement or specialisation of
//code in your base class.
//Instead of using the literal name of the base class in your
//code, you should be using the special name parent, which refers
//to the name of your base class as given in the extends declaration
//of your class. By doing this, you avoid using the name of your base
//class in more than one place. Should your inheritance tree change
//during implementation, the change is easily made by simply
//changing the extends declaration of your class.
<?php
class A {
function example() {
echo "I am A::example() and provide basic functionality.<br />\n";
}
}
class B extends A {
function example() {
echo "I am B::example() and provide additional functionality.<br />\n";
parent::example();
}
}
$b = new B;
// This will call B::example(), which will in turn call A::example().
$b->example();
?>
I would recommend you change your strucutre a little to "extend":
class second extends first{
public __construct(){
parent::__construct();
echo $this->variable;
}
}
Otherwise you will need to assign the "first" as a parent class within the variables on the second and actually access it like that:
class second{
public $first;
public function __construct($first){
$this->first = $first;
var_dump($this->first->variable);
}
}
Or of course you can also make the first class static and access it that way.
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();
I have a function that gets a class passed to it as a parameter. I would like to get the class name of the passed class as a string.
I tried putting this method in the passed class:
function getClassName()
{
return __CLASS__;
}
but if the class is extended I assumed this would return the name of the subclass but it still returns the name of the super class which I find kind of odd.
So given a $var passed to a function as a parameter, is there a way to get a string of the class name?
Thanks!!
See get_class, that should be exactly what you're trying to achieve.
$class_name = get_class($object);
Simplest way how to get Class name without namespace is:
$class = explode('\\', get_called_class());
echo end($class);
Or with preg_replace
echo preg_replace('/.*([\w]+)$/U', '$1', get_called_class());
__ CLASS __ with return the name of the class the method is implemented in.
If you want to get the class name of an object passed then you can use:
get_class($param);
Also, if you're using PHP5 then the Reflection classes provided are also useful.
Use get_class:
$className = get_class($object);
Straight from the php docs: http://uk.php.net/manual/en/function.get-class.php
<?php
abstract class bar {
public function __construct()
{
var_dump(get_class($this));
var_dump(get_class());
}
}
class foo extends bar {
}
new foo;
?>
The above example will output:
string(3) "foo"
string(3) "bar"
you could also add a method into the passed class(es) returning this:
var_dump(get_called_class());