Is it important to explicitly declare properties in PHP? - php

I have followed a tutorial to create a simple blog writing application in PHP and have modified the classes in this tutorial so that they have additional capabilities. Modifying this very bare bones app has given me a better understanding of how PHP works, however I have run across an interesting situation.
One of the classes in my project has about a half dozen class properties such as public $id, public $author, public $post. These properties are declared at the beginning of this class however I find that if I remove all but one of these properties the app still functions correctly.
Is it wrong to remove a property declaration such as public $datePosted from the beginning of a class if this class still assigns variables to this property like this: $this->datePosted = $someVariableName;

If you try to access a class property which hasn't been declared, PHP will issue a notice:
class Foo { }
var $fu = new Foo();
echo $fu->baz;
Notice: Undefined property: Foo::$baz in blah.php on line 4
If you set a value first ($fu->baz = 'blah') then it won't complain, but that's not a great situation.
You should definitely declare all your class variables (unless of course you want to have some fun with the magic methods)...

it's clearer for anyone reading your code that the members have been explicitly defined as public rather than just defaulting to it because you haven't assigned them as being public members.
Also, $this->$datePosted is wrong, it should be like this:
$this->datePosted = $someVariable;
which may be why you are experiencing an error.

PHP is really loose about how it handles class member definitions. You technically don't have to declare them. But you should, for two big reasons:
People with smart IDE's (Eclipse, Aptana, Zend Studio) will love if they can take advantage of their editor's code intellisense (auto-complete) while working with your classes. This feature really helps prevent against bugs involving typos. If you don't declare your fields, the IDE has no real way of determining the class' fields.
Someone just getting done working with a compiled language (C++) will likely send a hitman after you if they see a lack of properly-defined fields. It's just good practice to declare them. There's no reason not to.

Also, if you remove declaration and the code reads this variable prior to writting to it, you will have an error like
PHP Notice: Undefined property:
A::$unexistent in C:\temp\test.php on
line 8
Notice: Undefined property:
A::$unexistent in C:\temp\test.php on
line 8

Related

calling static method with static class variable as class name in php

I know you can call static methods using variable as class name like so:
$className = "Foo";
$className::Bar(); //works
But when i'm trying to use static property as variable like this:
self::$className = "Foo";
self::$className::Bar(); //doesn't
it gives me the following parse error on line where i'm trying to call the method:
Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)
So how can i call that method using static property and is that even possible with syntax somewhat similar to what i described(w/o call_user_func and creating local variable that stores self::$className)?
You could do that:
$tmp = self::$className;
$tmp::Bar();
Edit
Based on your comments it seems your problem is more about OOP design than it is about syntax. Furthermore, you keep adding new restrictions every time a solution is given, which makes it difficult to provide a relevant answer.
Anyway, I'll try to summarize your options. The syntax you want does not exist (at the moment, anyway), so you have to work around it one way or another. Yes, this is annoying, and yes this means that you will have to make concessions. But that's how it is.
Here are your options so far:
Use call_user_func or forward_static_call or similar.
Use a temporary local variable. Possibly wrap that into a method if it's really bothering you (e.g. static function call($method) { $tmp = self::$classname; return $tmp::$method(); } and then use self::call('bar');)
Refactor your object design using instances instead of static methods so that you don't need to do that anymore.
Use some other terribly ugly and dangerous hack (e.g. eval(self::$classname.'::bar();'); and hope it won't come bite you in the butt.

Why do these lines of code execute successfully

I'm very familiar with OOP in C++ and Java and I'm new to it in PHP, afterall PHP claims to support OOP. I'm refactoring some codes given to me in my internship and I came across the following style of coding, in PHP.
<?php
class A {
public function echoVar(){
$this->__();
echo $this->var;
}
}
class B extends A{
function __(){
$this->var = 1;
}
}
$v = new B();
$v->echoVar();
Following my experience with C++ and especially Java, this wouldn't even try to compile, but the execution is fine in PHP. I understand that all languages aren't the same but why does PHP support this style. Is this style good or bad practices? how is this OOP?
With my knowledge, the following are what I think is wrong with this code.
var is not a defined attribute of the class B, and yet was accessed and given a value.
How/Why did super class A have access to method __ of subclass B without casting or abstraction.
I would ask how class A got access to the attribute var but the attribute itself was created out of magic. On a serious note, why did it have access to var.
I'm a OOP newbie in PHP, so please help me clarify these things.
This is an example of, uhm, not so great coding. First, I would suggest activating strict error reporting (E_ALL | E_STRICT | E_NOTICE).
If an class/object property which hasn't been declared before, is assigned a value, it is going to be created as public property of the object. However, with strict error reporting, you'd get thrown an E_NOTICE.
Although the __ belongs to the B class, it can be called from A, when B is instantiated. The method is not declared as public/protected/private, so it's public by default, therefore accessible by parents/children as well as from the outside.
Of course, this is generally poor coding style, at least A would demand the implementation of __ in child classes with the following line: abstract public function __();.
Last, but not least, the function name __ is against PHP conventions, as methods starting with two underscores are reserved.
I would describe PHP as a language that tends to make assumptions when things are unclear, whereas C++ and Java are languages that force you to explicitly write everything out, or else they will throw errors.
Question #1 - In PHP you do not explicitly need to declare class properties in order to be able to assign them later, as you have discovered. Obviously though, if you immediately tried to echo $this->var; inside a class without assigning it, it would be undefined.
Question #2 - So this one's a little weird, but basically, if you create a superclass from a subclass, and you call a method inside a method defined in the subclass, the superclass version will get called. So even though __() is not defined in A, it is in defined in B, so if you create an A object, and called echoVar(); you will get a message about the method __() is undefined, you can still call echoVar(); in an object of type B, as __(); is defined there.
Question #3 - Similar to #2, even when used in the subclass, the superclass version of variables will be used.
I personally would try to never use this style of coding, however. As I'm sure you're already aware, it's not a good idea to make a class dependent on its superclass like that. It would be better to explicitly declare these things.
As for how it is OOP, the code you posted is primarily using objects as opposed to free floating functions or lines of code.

Use of declaring empty function in php

while seeing word press core code in depth i came across a file which has many empty functions for eg :
/**
* #ignore
*/
function apply_filters() {}
i realy dont know what is the use of declaring empty function in php..
i found this in wp-admin/list-scripts.php on line 34 - 37
and in wp-include/plugin.php on line 163 - 207 the same function is re declared with some works in it
In total i have 2 questions
What is the use of declaring an empty function in php
Why wordpress din't show any Fatal error: as the same function is already declared. ?
In PHP (and many other OOP languages), an empty function (or, more precisely, method) can be used in an interface. Any class inheriting that interface must implement the declared functions. However, last time I checked (which is, 2 minutes ago), WordPress isn't really an OOP system, so forward to 2.
list-scripts.php is not a default WordPress file - I can't find it in any of my WP installation. You may want to test by putting a die('called'); on top of the file and see if it gets executed. Therefore, WordPress won't encounter duplicated function declaration, and no fatal errors are introduced.
Now, even if list-scripts.php is a default WP file, when working with WP (and PHP in general) more often than not you see this:
if (!function_exists('apply_filters')) {
function apply_filters($arg1, $arg2) {
// code is poetry
}
}
This makes sure a function is only declared if it hasn't been before, and avoids the fatal error.
I guess wordpress will conditionally include either one or the other file. A lower level API of wordpress expects this functions to be defined and calls them. The extension itself is free to implement the function or not, however it has at least to provide the empty function body. The concepts behind this are much like interfaces work in OOP.

Use undefined constants on purpose

So I have a project called WingStyle: https://github.com/IngwiePhoenix/WingStyle
It is yet in development, and i need something to make it a little smarter.
In a way I want to get away from some quotes - take "html" as example. When the user calls a function which isn't there yet, the framework auto-loads the class for that purpose and then runs the function. In the process of auto-loading, there is a __construct method being triggered.
Let's take the function color as example. In the normal case, a user would call it like this:
<?=WS(...)
->color("white")
->end?>
But as you may know, we have a set of default colors - white, black, red, orange, etc, etc. Now the problem is that when I try to use the above code WITHOUT quotes, I get the typical "use of undefined constant" error. That is why I coded in a loader function which only triggers the initializing code which then adds the constants needed.
As far as I know, the interpreter sees the undefined constant before executing the code - so of course, I can't trigger the initializing code before the constant comes in...
Is there a way in which I can make the interpreter first trigger the initializing code and THEN see the constant? I don't mind sticking with my load-method really, but it just gets annoying adding things to it. I would really like to know of a way in which I could add the constants on the fly.
Check out the projects source to see what I mean.
The functions and mechanisms in questions are found in:
classes/WingStyleBase.php:
- addDefs()
classes/WingStyleManager.php
- __get()
I don't think there's a good way to add dynamic constants in PHP, though in theory you could write and then import a custom *.php file or something.
Of course, that's breaking what "constant" means. If it's going to change at run-time, you really want a global variable.
And neither would help you here, since if you or someone else calls ->color(white) white will be evaluated BEFORE it's passed to color, in the context of your calling application. If you want to allow that behavior to happen, just declare a white constant early on and use it with wild abandon in your code.

"this" mandatory for member access from inside the class body in PHP?

Coming from C++ I am used to be able to access class members directly in the body of their class, however, this doesn't seem to work in php - simple setters and getters fail to work unless explicitly using $this-> to access them. Setters seem to set to a temporary object that gets discarded and getters generate an error of trying to access non-existing objects.
Is there a way to directly access members inside the class body without the this keyword in php?
No, there is not. Setting an undefined variable will create it for the current scope, so that's what you're observing. (This is not a member variable though) - You can even read from an undefined variable, in which case the value will be null. This will generate an E_NOTICE though, so it's not considered good style.
Please read http://php.net/manual/en/language.oop5.php give a code snippet to see the exact problem you are facing

Categories