Why is a PHP class method called on instantiation? - php

Need some help understanding what's going on in my PHP code.
index.php
include("cache.php");
$cache = new Cache();
cache.php
class Cache {
private static $URL_CACHE;
public function cache($url, $entityId) {
echo '<br>caching '.$url.' as '.$entityId;
}
When I request index.php, I get 'caching as' displayed, which is a surprise. I never called $cache->cache('', '');
What's calling the method?
As per Blake's answer, since the method name matches (somewhat) the class name, it's called on instantiation. For Java developers this will certainly be a surprise.

This is using deprecated PHP functionality to act as a __contruct() method. In older versions of PHP (Removed in 7) If you had a class named Foo and a function named foo() it was how you would call it as a constructor.
In short, this is being called by you instantiating the class. If you change your cache() method to makeCache() I bet it will go away.
Another solution is to have an empty constructor as well, thanks JimL.
public function __construct() {
}

Related

Why is __constructor needed in codeigniter

Why does __constructor code needs to run in codeigniter controller and models ? Without those lines, the code is working fine. I am confused !
function __construct()
{
parent::__construct();
}
The reason behind for using the _construct(magic Function) is to load your library and helpers through the controllers, so that you don't have to load libraries and helpers in each of your functions.
Example:
function __construct() {
parent::__construct();
$this->load->library('someclass');
$this->load->helper('someclass');
}
It will work as long as the class from your controller/model does not need it's constructor method to be called. If the class from where it extends defines dependencies needed (for example), you may get unwanted results.
Even though the constructor method is a so called "magic method" and it will be called automatically when you use the new keyword (note that you have to use parenthesis):
$foo = new Foo();
This does not mean that the class from where Foo is extending will get it's constructor method called automatically.

Running code in a PHP once

I'm trying to write a class in PHP that acts as a wrapper for a collection of command line tools to make them easier to use from PHP.
I have a single class (MyClass) in a file myclass.php.
I have code that checks to see if the required tools are installed and then sets a constant (TOOLS_AVAILABLE) to either true or false. Although it's not a lot of code, I only want it to run the first time somebody tries to instantiate my class or use any of its static functions. What's the best practice for handling this?
I only want it to run the first time somebody tries to instantiate my class or use any of its static functions.
Well, the best answer is not to have any static methods. Then you can stick the code in a constructor method as per the answer by #treegarden.
If you must have static methods, then you'll need a static flag within the class to indicate when you've called the 'run once' code, so you can avoid running it again. And then call it explicitly from each of your static methods and the constructor. Something like this:
<?php
class myClass {
private static $hasRunOnce = false;
private static runMeOnce()
{
if (!self::$hasRunOnce) {
self::$hasRunOnce = true;
//put your 'run once' code here...
}
}
public static oneOfYourStaticMethods()
{
self::runMeOnce();
//put your static method code here...
//this would be the same for each of your static methods and your constructor.
}
}
Hope that helps.
You need to create a __construct function in your class and put whatever code you want to execute on instantiation in there:
class MyClass {
function __construct(/* arguments */) {
/* your code here */
}
}
The code will get executed only once when someone instantiates the class.

Why is this method called without being asked to?

I came across this very strange behavior.
The following code
class TestClass {
function testClass() {
echo "Don't show me!";
}
}
$testing = new TestClass;
executes its method testClass without it being called!
However, testClass won't run if renamed into anything else like testClass1.
Is there any hidden 'PHP magic' behind this behaviour?
EDIT.
At the end I see this question is trivial to ninjas grown up with PHP. As recent newcomer to PHP, I've learned to use __construct as constructor. With that "relic behaviour" carefully removed from modern tutorials. I am so glad people realized how terrible it was, changing class name and forgetting to change that of the constructor - what a nightmare!
Pre-PHP5, the __construct method was not used as the class constructor. Instead, a method with the same name as the class was used.
From the documentation:
For backwards compatibility, if PHP 5 cannot find a __construct() function for a given class, and the class did not inherit one from a parent class, it will search for the old-style constructor function, by the name of the class. Effectively, it means that the only case that would have compatibility issues is if the class had a method named __construct() which was used for different semantics.
Creating a (empty) constructor (method named __construct) will stop the message from being echoed upon class initialization (only needed for < PHP 5.3.3 *):
class TestClass {
function __construct() {
}
function testClass() {
echo "Don't show me!";
}
}
* As of PHP 5.3.3, methods with the same name as the last element of a namespaced class name will no longer be treated as constructor. This change doesn't affect non-namespaced classes.
In older versions of PHP a method with the same name as the classname was considered the constructor.

Calling static method non-statically

I have a child class that extends a class with only static methods. I would like to make this child class a singleton rather than static because the original developer really wanted a singleton but used static instead (obvious because every method in the static class calls the Init() function (basically a constructor)).
Most of the methods in the parent don't need to be overwritten in the child, but I would like to avoid having to write methods like this:
public function Load($id)
{
return parent::Load($id);
}
when I would prefer not to overwrite the method at all and just use:
$child->Load($id);
Is it possible to call a static method non-statically? Is it possible to extend a static object with an instance object? I know I can try it and it will likely work (PHP is very forgiving), but I don't know if there is anything I should be concerned about.
Can you inherit static methods?
Yes
Can you override static methods?
Yes, but only as of PHP 5.3 do they work as you would expect: http://www.php.net/manual/en/language.oop5.static.php (ie. self binds to the actual class and not the class it's defined in).
Is it possible to call a static method non-statically?
Yes, but will lose $this. You don't get a warning (yet) but there also isn't really a reason to call it the wrong way.
Two part answer.
First, about the titular question: calling a static method non-statically is perfectly fine; #SamDark's comment is correct. It does not produce a warning, nor does it cause any kitten murdering. Try it:
<?php
class test {
public static function staticwarnings(){
echo "YOU ARE (statically) WARNED!\n";
}
}
error_reporting(E_ALL);
$test = new test();
echo "\n\ncalling static non-statically\n";
$test->staticwarnings();
If you had an instance reference, $this, in that static method, then you would get a fatal error. But that is true regardless of how you call it.
Once again, there isn't a warning, nor any kitten killed.
Second part of the answer:
Calling an overridden parent function from an overriding child class requires something called "scope resolution". What the OP is doing in their method is NOT calling a static method. (Or at least, it doesn't have to be; we can't see the parent implementation). The point is, using the parent keyword is not a static call. Using the :: operator on an explicit parent class name is also not a static call, if it is used from an extending class.
Why is that documentation link so strangely named? It's literally Hebrew. If you've ever run into an error related to it, you might have observed the delightfully-named parser error code T_PAAMAYIM_NEKUDOTAYIM.

__construct() vs method with same name as class

I have recently started php and was wondering the differences between __construct() and having a method with the same name as the class?
Is there a reason for using it? All I can work out is it overrides the method named Foo or is it down to which you prefer?
E.g.
class Foo {
function Foo()
{
echo 'Foo stated<br>';
}
function __construct() {
echo 'Construct started<br>';
}
}
Thanks
Using __construct() is the newer PHP5 more OOP focused method to call a constructor. Using a method with the same name as the class is the old deprecated way to do it, and it will not function as a constructor as of PHP 5.3.3 for namespaced classes.
From the constructors and destructors page:
For backwards compatibility, if PHP 5 cannot find a __construct() function for a given class, it will search for the old-style constructor function, by the name of the class. Effectively, it means that the only case that would have compatibility issues is if the class had a method named __construct() which was used for different semantics.
Unlike with other methods, PHP will not generate an E_STRICT level error message when __construct() is overridden with different parameters than the parent __construct() method has.
As of PHP 5.3.3, methods with the same name as the last element of a namespaced class name will no longer be treated as constructor. This change doesn't affect non-namespaced classes.
"if PHP 5 cannot find a __construct() function for a given class, it will search for the old-style constructor function, by the name of the class. Effectively, it means that the only case that would have compatibility issues is if the class had a method named __construct() which was used for different semantics."
Source: http://www.php.net/manual/en/language.oop5.decon.php
Foo() is a php4 way(deprecated), __construct() is php5 way. php will first look for __construct, then, if it's not found, it will use Foo
Is there a reason for using it? All I
can work out is it overrides the
method named Foo or is it down to
which you prefer?
The benefits of __construct() become clearer when you involve renaming and inheritance. If you rename a class, you then have to rename it's constructor. No big deal, but if class B inherits from class A you could end up with:
class B extends A {
function B() {
parent::A();
}
}
It's much easier and more maintainable to do:
function __construct() {
parent::__construct();
}
Now when you rename class A, you don't have to remember to also change the parent calls in all its children. Granted, there's still renaming to do in your code but at least this is not one of them.
Having a method with the same name as the class, which is automatically called as a constructor is a throwback to PHP4, and is to be considered deprecated... in the latest development branch of PHP, it will be treated as a normal class method. __construct is the formally accepted constructor in PHP5, although in current releases it will fall back to the PHP4 method if __construct doesn't exist.

Categories