Is the "static" keyword necessary in PHP? - php

It seems that the uaa() function can be used as a static function even though it is not specifically defined as such. I'm wondering if using the "static" keyword is ever necessary.
<?php
class foo
{
functon uaa()
{
// do something
}
}

I'm not sure. But if you do that it triggers an E_STRICT:
Strict Standards: Non-static method
a::non_static() should not be called
statically in c:\file.php on
line 12
It is probably wise to be explicit about what is static and what isn't, at least so you are less likely to do something like try to access $this not in object context.

Strictly speaking, you can call a non-static function statically. You will generate an E_STRICT error though. And if you use $this in the method, you'll get a bigger error (I'm pretty sure it's an E_WARNING, but it may be more significant).
The static keyword was put in for enforcement. It's to prevent you from trying to call a static method from an instance. So while it's not strictly needed, it is good design practice to use it to identify and partially enforce the appropriate calling.
Plus, it's there to "future proof" your code. What I mean is that in later versions of PHP, they may remove the "feature" when you can call non-static methods statically (Which is why it's an E_STRICT error now).

Related

PHP/CodeIgniter 2 - call object's __get() method only for a particular object

I'm working on old CodeIgniter 2 code that I can only change by adding a layer on top, so I'm limited.
Often in the code, a property $this->secondary_db is often called even before it was initialized, like such:
$this->secondary_db->get_all();
Which obviously end up with a Fatal error since secondary_db is null.
So, what I tried to do was implement the magic __get($name) method but ONLY for secondary_db so it would only use the magic method when $this->secondary_db is not defined by specifying in the magic method:
if ($name == 'secondary_db') { ... load db in a specific way ... }
However it creates other fatal errors from other bits of code somewhere that rely on __get() not being called, like such:
Indirect modification of overloaded property Some_Controller::$benchmark has no effect
Cannot assign by reference to overloaded object in system/core/Controller.php
Is there another way to do this or achieve the same thing that I might have forgotten about? Could traits be used for that?
NOTE: I cannot initialize secondary_db in the constructor since it's not always the same value.

Static methods in PHP: what for?

I'm terribly sorry for asking such a silly question, but I'm new to OOP and trying to figure out what static methods are used for. Here's an example PHP code:
class foo{
static function bar(){
//do something here
}
public function baz(){
//do something different
}
}
Documentation says:
Declaring class properties or methods as static makes them accessible without needing an instantiation of the class
However, the both methods from the example above can be accessed from outside of the class with like:
foo::bar();
foo::baz();
It works (at least for PHP 5.3 that I'm using) without instantiation of the class foo.
So, what's the point of using static methods, if the both ways work??
Forgive me once again for such a noob question. I've been really trying hard to find it out myself with no success. Thanks.
Static methods are globally available tools (helpers) and are often overused. Static methods are death to testability and should be avoided almost completely.
Their advantage as well as disadvantage is that they live in the global scope, you can call them from anywhere, which makes them code smells in most cases because they break encapsulation.
On language level, as Kolink mentions, things like mysqli:real_escape_string() make sense of course, but on application level, you usually don't want to pollute your global scope and break encapsulation like that. You'd rather think of what tools you really need and where and inject them bundled into meaningful groups (classes).
Your foo::baz() raises a warning in strict mode (which should always be on):
Strict standards: Non-static method foo:baz() should
not be called statically in yourfile.php on line x
Generally they can be used for "helper" functions, such as mysqli::real_escape_string(), where the function is relevant to the class but not locked to any specific instance of it.

PHP => Call to non-existing class constants, way to handle?

just like the __call magic method we can use in PHP to hook a call to a non defined method, is there a way to hook a call to an undefined constant or variable?
Like A::B, where B doesn't exist.
No. Constants are evaluated at opcode compile time not runtime, so there's no way to 'catch' them. There is still an issue with php related to this where a parent class cannot call a childs constant inside a parents method.
You're probably looking for __get and __set. I'm not really sure how it works with static constants though, you might only be able to work with instanced objects. See G-Nugget's comment regarding using them statically.

How to silence warnings

I have a class that inherits from a another class.
I am overloading one method; PHP screams about this.
How do I silence this message? It clutters my debug logs.
Declaration of
Dashboard_Abstract::factory() should
be compatible with that of
Abstract::factory()
class Abstract{
static public function factory($param){
...
...
}
}
class Dashboard_Abstract extends Abstract{
static public function factory($param1,$param2){
...
...
}
}
Look, fellow developers. There is a difference between errors and warnings:
means,
"Look, if you are new to this you
might be doing something wrong here,
If you are experienced, you might be
doing right, so we will let you, the
developer, decide."
So, why won't you let me decide?
Is it so bad to use all of a language abilities to the max, even if some think it is an error (although, obviously, it is not).
You can use the error_reporting() function to override it at runtime, and there's an identically named parameter in php.ini you can set to make the change permanent. However, warnings are there for a reason and generally you should fix your code instead of just silencing them.
Well, since it is a specialized class, altering the method signature should not trigger a warning. It doesn't in pure OOP languages. And E_STRICT is really a special kind of purposed warning message (trying to impose a non-semantic coding standard).
But anyway, there is an easy workaround for your case. You can make the method signature compatible by just making parameters optional in the overriding method:
class Abc {
static public function factory($param) { }
}
class Xyz extends Abc {
static public function factory($param1, $param2=NULL) { }
}
Notice the $param2=NULL in the overloading method signature. With this trick the more specialized class/object can still be used where a parent object was expected.
You might use an assert($param2!==NULL) within the method instead if it is required.
(The E_STRICT notice for eventually undefined parameters in your static factory methods -which are only ever used with explicit classnames- really makes no sense here. But won't get fixed http://bugs.php.net/bug.php?id=41461 in the php.net implementation.)
You're not overriding it correctly because the number of variables has changed. It will continue to yell at you about this, as it should. Keep the number of arguments the same, use default arguments if you have to.
You should fix the problem. If you have a child class overriding a method in a parent class, the signature of the method must be compatible. That means that it must have the same or greater visibility, the same staticity (?!) and the same number or fewer arguments.
Either Abstract should take two parameters, or Dashboard_Abstract should take one. I can't tell you which way round it should be without seeing what these classes actually do...
You shouldn't silence that message, instead you should make sure that the overriding method is compatible with the original one. If you need the overriding method to accept a different number of parameters, you could rewrite the original method to use a dynamic list of arguments - see http://php.net/manual/en/function.func-get-args.php

Should a function be used in both static and object context

In my company's codebase, i see functions used in both static and object context. For e.g. a class A has a function b() which is called both using A::b() and/or object_of_type_A->b(). I know this throws an error if strict is turned on. But I wanted to know if this is a bad practice and if yes, then why? Thanks for any answers.
Let me know if I don't make sense anywhere. I would be happy to clarify.
I'm not a php guy, but this sounds just like Java, where it's allowed but discouraged.
If it's static, I would strongly recommend only calling it in a static way. Otherwise it looks like it depends on the state of the object you're supposedly calling it on.
In Java the best example of this is Thread.sleep(). It's a static method which puts the current thread to sleep, always. But look at this code:
Thread t = new Thread(someTask);
t.start();
t.sleep(1000);
What does it look like that code is doing? It appears to be putting the other thread to sleep, whereas in fact it'll be the current thread that's sleeping. When you change it to a plain static call, it's more obvious:
Thread.sleep(1000);
That doesn't refer to t, so must be about the current thread.
Unless there's something specific to php where calling the static method via a variable gives you some sort of polymorphism, I suggest you stick to calling it in the static way. The fact that strict mode tells you to do this is a pretty strong hint, IMO :)
Here's some test code:
<?php
error_reporting(E_ALL | E_STRICT);
class Foo{
public function a(){
}
public static function b(){
}
}
$MyFoo = new Foo;
Foo::a(); // Strict Standards: Non-static method Foo::a() should not be called statically
Foo::b();
$MyFoo->a();
$MyFoo->b(); // No complaints
?>
PHP/5.3 warns about static calls to non-static methods, which is fine since they are subject to failure as soon as you want to access $this. But it does not complain about object context calls to static functions: there's nothing that can go wrong. This behaviour is documented:
Declaring class properties or methods
as static makes them accessible
without needing an instantiation of
the class. A property declared as
static can not be accessed with an
instantiated class object (though a
static method can)
[...]
Because static methods are callable
without an instance of the object
created, the pseudo-variable $this is
not available inside the method
declared as static.
So, as far as PHP is concerned, what you found in the code base is not wrong. However, I think it's slightly confusing.
There is 'currently' no harm in using it either way except of course when called as a static function you can't access the $this member.
The reason it errors in strict is because not writing your code to strict standards can result in errors occurring due to a lack of diligence. in the future it may also cause your code to break. a static function has no $this member and it may break parameter passing.
Play it safe only call static functions with A::b() type calls.
DC
Regarding accessing $this in a static function I found something a bit strange a while back (might be changed in later versions of PHP though, think I ran 5.2 or something).
You can read about it here but it's in swedish. But use google translate and it should be understandable.
http://www.phpportalen.net/viewtopic.php?p=560080#560080

Categories