Narendra Dhami

My Site

OO PHP Part 1: OOP in Full Effect

Posted by Narendra Dhami on July 2, 2008


4. Hot off The Press Features
4.1 Namespaces

PHP 5.3 and up offers namespaces which allows you to give your classes logical names without resorting to really long winded names like the ones caused by the PEAR naming standard.

Simply put, the PEAR naming standard defines pseudo namespaces, which map to a location on the file system (see section Autoload). A name like the following:

Application_Input_Validate_PhoneNumber_Us

Would map to Application/Input/Validate/PhoneNumber/Us.php

Sometimes these names get way bigger than this. Here’s a different example, from Zend Framework:

Zend_Controller_Action_Helper_AutoComplete_Abstract

It can get even bigger.

PHP 5.3+ namespaces solves this by creating aliases.
view plaincopy to clipboard

1. namespace Application::Input::Validate::PhoneNumber
2.
3. class Us {
4.
5. }

namespace Application::Input::Validate::PhoneNumber class Us { }

Now, I could call this:
view plaincopy to clipboard

1. $validator = new Application::Input::Validate::PhoneNumber::Us($arg);

$validator = new Application::Input::Validate::PhoneNumber::Us($arg);

But that can hardly be called an improvement, can it?

Instead, knowing that I am going to use a phone number validator, I can create a namespace alias:
view plaincopy to clipboard

1. use Application::Input::Validate::PhoneNumber as PhoneValidators
2.
3. $validator = new PhoneValidators::Us($arg);

use Application::Input::Validate::PhoneNumber as PhoneValidators $validator = new PhoneValidators::Us($arg);

Better, no? It saves me having to refer to the fully quantified class name, and I can select the right validator class in my client code without littering it with repeated lengthy namespace selections.

I can also create an alias for a class name. For example:
view plaincopy to clipboard

1. use Framework::Controller::Response::Http HttpResponse
2.
3. $response = new HttpResponse();

use Framework::Controller::Response::Http HttpResponse $response = new HttpResponse();

The fully quantified name of the class includes the namespace. Hence, calling var_dump on the above $response object would output something like the following:

object(Framework::Controller::Response::Http)#1 (0) {

}

This allows us to mend our __autoload function to load classes in a namespace:
view plaincopy to clipboard

1. function __autoload($className)
2. {
3. $file = str_replace(‘::’, DIRECTORY_SEPARATOR, $className) . ‘.php’;
4.
5. if(!file_exists($file))
6. {
7. return false;
8. }
9. else
10. {
11. require_once $file;
12. }
13. }

function __autoload($className) { $file = str_replace(‘::’, DIRECTORY_SEPARATOR, $className) . ‘.php’; if(!file_exists($file)) { return false; } else { require_once $file; } }

4.2 Late static binding

In PHP 5.2, you can already do this:
view plaincopy to clipboard

1. abstract class ParentClass
2. {
3. public static function foo()
4. {
5. echo ‘blah’;
6. }
7. }
8. class ImplementationClass extends ParentClass
9. {}
10.
11. ImplementationClass::foo();

abstract class ParentClass { public static function foo() { echo ‘blah’; } } class ImplementationClass extends ParentClass {} ImplementationClass::foo();

Static methods are inherited. But without late static binding, ParentClass will not be able to invoke any static methods of ImplementationClass, like in this non-static example:
view plaincopy to clipboard

1. abstract class ParentClass
2. {
3. public function foo()
4. {
5. $this->meh();
6. }
7. }
8. class ImplementationClass extends ParentClass
9. {
10. public function meh()
11. {
12. echo ‘blah’;
13. }
14. }
15.
16. $impl = new ImplementationClass();
17. $impl->foo();

abstract class ParentClass { public function foo() { $this->meh(); } } class ImplementationClass extends ParentClass { public function meh() { echo ‘blah’; } } $impl = new ImplementationClass(); $impl->foo();

If we wanted meh to be static, it would be tempting to try this:
view plaincopy to clipboard

1. abstract class ParentClass
2. {
3. public function foo()
4. {
5. self::meh();
6. }
7. }
8. class ImplementationClass extends ParentClass
9. {
10. public static function meh()
11. {
12. echo ‘blah’;
13. }
14. }
15. ImplementationClass::foo();

abstract class ParentClass { public function foo() { self::meh(); } } class ImplementationClass extends ParentClass { public static function meh() { echo ‘blah’; } } ImplementationClass::foo();

But self refers to the current class scope, ParentClass in this case, so we produce this error:

Fatal error: Call to undefined method ParentClass::meh()

In PHP5.3+, self still points to the current class reference. To make the above scenario possible, a new use is given to the static keyword:
view plaincopy to clipboard

1. abstract class ParentClass
2. {
3. public static function foo()
4. {
5. static::meh();
6. }
7. }
8. class ImplementationClass extends ParentClass
9. {
10. public static function meh()
11. {
12. echo ‘blah’;
13. }
14. }
15. ImplementationClass::foo();

abstract class ParentClass { public static function foo() { static::meh(); } } class ImplementationClass extends ParentClass { public static function meh() { echo ‘blah’; } } ImplementationClass::foo();

Above will echo ‘blah’ on PHP5.3+.

But, all is not as simple as it seems. The static keyword doesn’t take inheritance into account, like $this does. Instead it tries to resolve the correct call.

The following code will fail:
view plaincopy to clipboard

1. abstract class ParentClass
2. {
3. public static function delegate()
4. {
5. static::meh();
6. }
7. }
8. class ImplementationClass extends ParentClass
9. {
10. public static function meh()
11. {
12. echo ‘blah’;
13. }
14. public static function foo()
15. {
16. parent::delegate();
17. }
18. }
19. ImplementationClass::foo();

abstract class ParentClass { public static function delegate() { static::meh(); } } class ImplementationClass extends ParentClass { public static function meh() { echo ‘blah’; } public static function foo() { parent::delegate(); } } ImplementationClass::foo();

Because ‘parent’ resolves to ParentClass, ‘static’ in delegate() resolves to ParentClass as well. But ParentClass doesn’t have a method called ‘meh’; the dreaded fatal error we got before is inescapable. You’ll get similar results trying it with multiple levels of inheritance, a fully resolved method call (ParentClass::delegate()), or with static properties instead of methods.

Original Source : by John Kleijn on Jun 6, 2008 3:21:29 PM

and From PHP : php.net

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: