I\'ve been examining the code of CodeIgniter and CakePHP and I noticed that some of the methods in their classes are prefixed with an underscore _
or a double u
The methods that start with __ are magic methods which get called automatically in php. for more reference , check,
http://php.net/manual/en/language.oop5.magic.php
These are Magic Methods in PHP classes:
The function names
__construct, __destruct, __call, __callStatic, __get, __set, __isset, __unset, __sleep, __wakeup, __toString, __invoke, __set_state
and__clone
are magical in PHP classes. You cannot have functions with these names in any of your classes unless you want the magic functionality associated with them.
A method with one underscore has no special meaning. This is more likely some coding convention of the projects.
In the case where it is not any of PHP's magic methods, it is to indicate Visibility in lack of proper Visibility keywords:
Cake Coding Conventions:
As we cannot use PHP5's private and protected keywords for methods or variables, we agree on following rules:
- A protected method or variable name start with a single underscore ("_").
- A private method or variable name start with double underscore ("__").
CodeIgniter conventions:
Methods and variables that are only accessed internally by your class, such as utility and helper functions that your public methods use for code abstraction, should be prefixed with an underscore.
I'm not familiar with CakePHP or CodeIgniter, but I think they should be regarded as protected
or private
for non-CakePHP classes. They are probably public
as they can be called from other classes, making some kind of hack. Please note that __get
, __construct
and other magic methods (as noted above) exists in PHP.
In Codeigniter, methods within controllers can normally be called as part of the url so you might call the method "index" in controller "main" as follows:
mysite.com/main/index.
You might also have a method within your controller that you don't want someone to be able to call as a segment in the url, so you would prefix it with a "_" (single underscore) .. that is different than making it private. Private methods are only callable within the class where it is defined. So a controller method could be prefixed with an underscore which would make it uncallable as a url segment and it could also be declared private which would make it uncallable from other classes.
I have a use case for this that is my own preference. I will often write traits that are intended to honor a specific interface, although since traits cannot directly implement an interface, I will designate which interface the trait satisfies in the doc block comment, and prefix protected and private methods that are not related to the interface with a single underscore. This lets you pretty easily follow which methods are provided to satisfy the contract (interface), and which are supporting methods. Eg:
interface Foo {
public function bar(array $args = null, array $flags = null);
}
The trait below's purpose is to satisfy the requirements of the Foo
interface, but only one of it's methods are needed to do so. For clarity, the protected methods are prefixed. Even if they are made public by extension later, this still indicates that they are not contractually dependent by interface, and should not be assumed to be anything relevant.
/**
* @satifies Foo
*/
trait FooTrait {
public function bar(array $args = null, array $flags = null) {
$this->_handleArgs($args);
$this->_handleFlags($flags);
}
protected function _handleArgs(array $args = null) {
if (is_null($args) {
return;
}
//do something with the args
}
protected function _handleFlags(array $flags = null) {
if (is_null($flags) {
return;
}
//do something with the flags
}
}
You can then satisfy the interface by implementing it on a class and using the corresponding trait with no additional work.
final class ConcreteFoo implements Foo {
use FooTrait;
}
This keeps things very loosely coupled, and makes it possible to pretty easily integrate with other classes from other libraries or frameworks that do require a chain of inheritance without having to convolute your logic with a bunch of adapter classes.
My IDE (Netbeans) grumbles about this as a violation of PSR-1. As PSR-1 does not directly affect execution and it is arguable as to whether this is a more readable approach or not, I could really care less. I do try to follow all of the PSR's that directly affect execution though.