Is there any way to call a php class (eg. $var = new className) and have var store the value returned by the className function?
Or, is there a way to call a class and not have it execute the function with the same name?
The function of the same name as the class was they way 'constructors' in php 4 worked.
This function is called automatically when a new object instance is created.
In php 5, a new magic function __construct() is used instead.
If your using php5 and don't include a '__construct' method, php will search for an old-style constructor method.
http://www.php.net/manual/en/language.oop5.decon.php
So if you are using php5, add a '__construct' method to your class, and php will quit executing your 'method of the same name as the class' when a new object is constructed.
It is possible in PHP5 using magical method __toString(); to return a value from the class instance/object.
simply
class MyClass{
function __construct(){
// constructor
}
function __toString(){
// to String
return 5;
}
}
$inst = new MyClass();
echo $inst; // echos 5
Constructors don't return value (in fact you can't do that). If you want to get a value from the instance of the class, use the __toString() magical method.
Constructors don't return values, they are used to instantiate the new object you are creating. $var will always contain a reference to the new object using the code you provided.
To be honest, from your question, it sounds like you don't understand the intention of classes.
$var = new classname will always return an instance of classname. You can't have it return something else.
Read this...
http://www.php.net/manual/en/language.oop5.php
Related
For example, I have a class
class MyClass
{
public $something = 'base';
public function __construct()
{
$something = 'construct';
}
public function __destruct()
{
$something = 'destruct';
}
public static doSomething()
{
$return = new MyClass;
echo $return->something;
}
}
So, my question is this... Will running the static method without instantiating the object run the constructor? If I had, for example, database connection information in the constructor, could I run a static method that returns a query withing explicitly instantiating the class?
Thanks in advance
Yes the construction will be called in your example. Since you already have the code, I guess it would be easy to test.
If you execute MyClass::doSomething(), it will create object of MyClass and, of course, its constructor will be called. Why not to run it and see the result?
I'm lacking PHP knowledge, but compared to other OO languages it will of course run the constructor, because you tell the static method to create a new instance of MyClass.
The same would apply if you called a new SomeOtherType. The code itself doesn't care if it's inside a static/public/private method, as long as new is there, the constructor is invoked.
I did not ask the question correctly, but the answer is that as long as the object is instantiated, even within a static method, the constructor will run. The output would be whatever is in the constructor as the deconstructor does not fire until after the last call to the class.
Sorry for the confusion in the question.
Why in PHP you can access static method via instance of some class but not only via type name?
UPDATE: I'm .net developer but i work with php developers too. Recently i've found this moment about static methods called from instance and can't understand why it can be usefull.
EXAMPLE:
class Foo
{
public static Bar()
{
}
}
We can accept method like this:
var $foo = new Foo();
$foo.Bar(); // ??????
In PHP
the class is instantiated using the new keyword for example;
$MyClass = new MyClass();
and the static method or properties can be accessed by using either scope resolution operator or object reference operator. For example, if the class MyClass contains the static method Foo() then you can access it by either way.
$MyClass->Foo();
Or
MyClass::Foo()
The only rule is that static methods or properties are out of object context. For example, you cannot use $this inside of a static method.
Class Do {
static public function test() {
return 0;
}
}
use like this :
echo Do::test();
Why in PHP you can access static method via instance of some class but not only via type name?
Unlike what you are probably used to with .NET, PHP has dynamic types. Consider:
class Foo
{
static public function staticMethod() { }
}
class Bar
{
static public function staticMethod() { }
}
function doSomething($obj)
{
// What type is $obj? We don't care.
$obj->staticMethod();
}
doSomething(new Foo());
doSomething(new Bar());
So by allowing access to static methods via the object instance, you can more easily call a static function of the same name across different types.
Now I don't know if there is a good reason why accessing the static method via -> is allowed. PHP (5.3?) also supports:
$obj::staticMethod();
which is perhaps less confusing. When using ::, it must be a static function to avoid warnings (unlike ->, which permits either).
In PHP, while you're allowed to access the static method by referencing an instance of the class, you don't necessarily need to do so.
For example, here is a class with a static function:
class MyClass{
public static function MyFunction($param){
$mynumber=param*2;
return $mynumber;
}
You can access the static method just by the type name like this, but in this case you have to use the double colon (::), instead of "->".
$result= MyClass::MyFunction(2);
(Please note you can also access the static method via an instance of the class as well using "-->"). For more information: http://php.net/manual/en/language.oop5.static.php
In PHP 7 it seems to be absolutely necessary for you to be able to do $this->staticFunction(). Because, if this code is written within an abstract class and staticFunction() is also abstract in your abstract class, $this-> and self:: deliver different results!
When executing $this->staticFunction() from a (non-abstract) child of the abstract class, you end up in child::staticFunction(). All is well.
However, executing self::staticFunction() from a (non-abstract) child of the abstract class, you end up in parent::staticFunction(), which is abstract, and thusly throws an exception.
I guess this is just another example of badly designed PHP.
Or myself needing more coffee...
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Benefits of using a constructor?
hello coders. I am newbie to OOP in php. I am doing a project in objects and class. where
most of time I face a line
public function __construct(){
}
I can't understand this. Why its used and what is its value. Can some one tell me about it. I went to the php.net site but my doubt not cleared.
when using oop, a constructor gives basic initialization details for an object.
See:
http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)#PHP
The __construct allows arguments to be passed to an object on initalisation, without you would do something like this:
$myobj = new Object();
$myobj->setName('Barry');
But if you have this:
public function __construct($name='')
{
$this->name = $name;
}
You can just do:
$myobj = new Object('Barry');
Another possible use for the constructor (though not good practice):
public function __construct()
{
ob_start(); //Some random code that you may want to run as soon as object is initialised
}
It's a method within a class. When you construct an object from a class, this associated constructor is called. It has the "__" magic method prefix.
This method is automatically called when a class is instantiated.
There is also a __destruct() method, which as you might guess is automatically called when a class is destroyed.
Have a read here:
http://php.net/manual/en/language.oop5.decon.php
The value of the __construct is to initialize any newly created object in a method that's native to OO design.
So, rather than doing something like this:
$o = new MyObject();
$o->Initialize();
We can simply do this:
$o = new MyObject();
And within the MyObject class:
class MyObject
{
public function __contruct()
{
// initialization code here
}
}
Is it possible in PHP (as it is in C++) to declare a class method OUTSIDE the class definition?
No, as of PHP 5.2. However, you may use __call magic method to forward call to arbitrary function or method.
class A {
public function __call($method, $args) {
if ($method == 'foo') {
return call_user_func_array('bar', $args);
}
}
}
function bar($x) {
echo $x;
}
$a = new A();
$a->foo('12345'); // will result in calling bar('12345')
In PHP 5.4 there is support for traits. Trait is an implementation of method(s) that cannot be instantiated as standalone object. Instead, trait can be used to extend class with contained implementation. Learn more on Traits here.
Yes it is possible to add a method to a PHP class after it is defined. You want to use classkit, which is an "experimental" extension. It appears that this extension isn't enabled by default however, so it depends on if you can compile a custom PHP binary or load PHP DLLs if on windows (for instance Dreamhost does allow custom PHP binaries, and they're pretty easy to setup).
<?php
class A { }
classkit_method_add('A', 'bar', '$message', 'echo $message;',
CLASSKIT_ACC_PUBLIC);
$a = new A();
$a->bar('Hello world!');
Example from the PHP manual:
<?php
class Example {
function foo() {
echo "foo!\n";
}
}
// create an Example object
$e = new Example();
// Add a new public method
classkit_method_add(
'Example',
'add',
'$num1, $num2',
'return $num1 + $num2;',
CLASSKIT_ACC_PUBLIC
);
// add 12 + 4
echo $e->add(12, 4);
You could perhaps override __call or __callStatic to locate a missing method at runtime, but you'd have to make up your own system for locating and calling the code. For example, you could load a "Delegate" class to handle the method call.
Here's an example - if you tried to call $foo->bar(), the class would attempt to create a FooDelegate_bar class, and call bar() on it with the same arguments. If you've got class auto-loading set up, the delegate can live in a separate file until required...
class Foo {
public function __call($method, $args) {
$delegate="FooDelegate_".$method;
if (class_exists($delegate))
{
$handler=new $delegate($this);
return call_user_func_array(array(&$handler, $method), $args);
}
}
}
As PHP 5.3 supports closures, you can dynamically define instance methods as variables holding closures:
$class->foo = function (&$self, $n) {
print "Current \$var: " . $self->var . "\n";
$self->var += $n;
print "New \$var: " .$self->var . "\n";
};
Taking $self (you can't use $this outside object context) as a reference (&), you can modify the instance.
However, problems occur when you try to call the function normally:
$class->foo(2);
You get a fatal error. PHP thinks foo is a method of $class, because of the syntax. Also, you must pass the instance as the first argument.
There is luckily a special function for calling functions by name called call_user_func:
call_user_func($class->foo, &$class, 2);
# => Current $var: 0
# => New $var: 2
Just remember to put & before the instance variable.
What's even easier is if you use the __call magic method:
class MyClass {
public function __call ($method, $arguments) {
if (isset($this->$method)) {
call_user_func_array($this->$method, array_merge(array(&$this), $arguments));
}
}
}
Now you can call $class->foo(2) instead. The magic __call method catches the call to an unknown method, and calls the closure in the $class->foo variable with the same name as the called method.
Of course, if $class->var was private, the closure in stored in the $class->foo variable wouldn't be able to access it.
No.
You can extend previously declared classes, though, if that helps.
No it is not posible. if you define function/method outside class construct it becomes global function.
C++ can't do this either. Did you mix up declaration with definition?
No, as everyone has said, it is not strictly possible.
However, you can do something like this to emulate a mixin in PHP or add methods to a class at runtime, which is about as close as you're going to get. Basically, it's just using design patterns to achieve the same functionality. Zope 3 does something similar to emulate mixins in Python, another language that doesn't support them directly.
Is it ok to use a singleton method inside of a __constructor to initiate the class if it wasn't already?
No -- A singleton method is an alternative to using a constructor.
Instead of saying $session = new Session();
you should say
$session = Session::getStaticSession();
Then define Session::getStaticSession() as a function tht returns an internal static var, and calls "new Session()" if the internal static var is null.
If you create it in each constructor that uses it, then it isn't a singleton.
If you follow this tutorial then it should help you understand how to use the singleton design pattern in php.
http://www.developertutorials.com/tutorials/php/php-singleton-design-pattern-050729/page1.html
You can't use a singleton method inside a constructor, as the object has already been created, and you can't return anything. Your singleton method, on the other hand, needs to either return the current object or create a new one.
You can use a single method to do that, however, such as the following:
<?php
class X {
// ...
function instance() {
static $instance;
if(!is_a($instance, 'X')) {
$instance = new X();
}
}
?>