Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 108 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
108
Dung lượng
1,42 MB
Nội dung
182 CHAPTER 6 ■ OBJECT-ORIENTED PHP private function takeLunchbreak(Employee $employee) { } Keep in mind that type hinting only works for objects and arrays. You can’t offer hints for types such as integers, floats, or strings. Constructors and Destructors Often, you’ll want to execute a number of tasks when creating and destroying objects. For example, you might want to immediately assign several fields of a newly instanti- ated object. However, if you have to do so manually, you’ll almost certainly forget to execute all of the required tasks. Object-oriented programming goes a long way toward removing the possibility for such errors by offering special methods, called construc- tors and destructors, that automate the object creation and destruction processes. Constructors You often want to initialize certain fields and even trigger the execution of methods found when an object is newly instantiated. There’s nothing wrong with doing so immediately after instantiation, but it would be easier if this were done for you auto- matically. Such a mechanism exists in OOP, known as a constructor. Quite simply, a constructor is defined as a block of code that automatically executes at the time of object instantiation. OOP constructors offer a number of advantages: • Constructors can accept parameters, which are assigned to specific object fields at creation time. • Constructors can call class methods or other functions. • Class constructors can call on other constructors, including those from the class parent. This section reviews how all of these advantages work with PHP 5’s improved constructor functionality. Gilmore_862-8C06.fm Page 182 Tuesday, February 12, 2008 9:12 AM CHAPTER 6 ■ OBJECT-ORIENTED PHP 183 ■Note PHP 4 also offered class constructors, but it used a different more cumbersome syntax than that used in version 5. Version 4 constructors were simply class methods of the same name as the class they represented. Such a convention made it tedious to rename a class. The new constructor-naming convention resolves these issues. For reasons of compatibility, however, if a class is found to not contain a constructor satisfying the new naming convention, that class will then be searched for a method bearing the same name as the class; if located, this method is considered the constructor. PHP recognizes constructors by the name __construct. The general syntax for constructor declaration follows: function __construct([argument1, argument2, , argumentN]) { // Class initialization code } As an example, suppose you want to immediately populate certain book fields with information specific to a supplied ISBN. For example, you might want to know the title and author of a book, in addition to how many copies the library owns and how many are presently available for loan. This code might look like this: <?php class Book { private $title; private $isbn; private $copies; public function _construct($isbn) { $this->setIsbn($isbn); $this->getTitle(); $this->getNumberCopies(); } public function setIsbn($isbn) { $this->isbn = $isbn; } Gilmore_862-8C06.fm Page 183 Tuesday, February 12, 2008 9:12 AM 184 CHAPTER 6 ■ OBJECT-ORIENTED PHP public function getTitle() { $this->title = "Beginning Python"; print "Title: ".$this->title."<br />"; } public function getNumberCopies() { $this->copies = "5"; print "Number copies available: ".$this->copies."<br />"; } } $book = new book("159059519X"); ?> This results in the following: Title: Beginning Python Number copies available: 5 Of course, a real-life implementation would likely involve somewhat more intelligent get methods (e.g., methods that query a database), but the point is made. Instantiating the book object results in the automatic invocation of the constructor, which in turn calls the setIsbn(), getTitle(), and getNumberCopies() methods. If you know that such methods should be called whenever a new object is instantiated, you’re far better off automating the calls via the constructor than attempting to manually call them yourself. Additionally, if you would like to make sure that these methods are called only via the constructor, you should set their scope to private, ensuring that they cannot be directly called by the object or by a subclass. Invoking Parent Constructors PHP does not automatically call the parent constructor; you must call it explicitly using the parent keyword. An example follows: Gilmore_862-8C06.fm Page 184 Tuesday, February 12, 2008 9:12 AM CHAPTER 6 ■ OBJECT-ORIENTED PHP 185 <?php class Employee { protected $name; protected $title; function __construct() { echo "<p>Staff constructor called!</p>"; } } class Manager extends Employee { function __construct() { parent::__construct(); echo "<p>Manager constructor called!</p>"; } } $employee = new Manager(); ?> This results in the following: Employee constructor called! Manager constructor called! Neglecting to include the call to parent::__construct() results in the invocation of only the Manager constructor, like this: Manager constructor called! Gilmore_862-8C06.fm Page 185 Tuesday, February 12, 2008 9:12 AM 186 CHAPTER 6 ■ OBJECT-ORIENTED PHP Invoking Unrelated Constructors You can invoke class constructors that don’t have any relation to the instantiated object simply by prefacing __constructor with the class name, like so: classname::__construct() As an example, assume that the Manager and Employee classes used in the previous example bear no hierarchical relationship; instead, they are simply two classes located within the same library. The Employee constructor could still be invoked within Manager’s constructor, like this: Employee::__construct() Calling the Employee constructor like this results in the same outcome as that shown in the example. ■Note You may be wondering why the extremely useful constructor-overloading feature, available in many OOP languages, has not been discussed. The answer is simple: PHP does not support this feature. Destructors Although objects were automatically destroyed upon script completion in PHP 4, it wasn’t possible to customize this cleanup process. With the introduction of destruc- tors in PHP 5, this constraint is no more. Destructors are created like any other method but must be titled __destruct(). An example follows: <?php class Book { private $title; private $isbn; private $copies; function __construct($isbn) { echo "<p>Book class instance created.</p>"; } Gilmore_862-8C06.fm Page 186 Tuesday, February 12, 2008 9:12 AM CHAPTER 6 ■ OBJECT-ORIENTED PHP 187 function __destruct() { echo "<p>Book class instance destroyed.</p>"; } } $book = new Book("1893115852"); ?> Here’s the result: Book class instance created. Book class instance destroyed. When the script is complete, PHP will destroy any objects that reside in memory. Therefore, if the instantiated class and any information created as a result of the instantiation reside in memory, you’re not required to explicitly declare a destructor. However, if less volatile data is created (say, stored in a database) as a result of the instantiation and should be destroyed at the time of object destruction, you’ll need to create a custom destructor. Static Class Members Sometimes it’s useful to create fields and methods that are not invoked by any particular object but rather are pertinent to and are shared by all class instances. For example, suppose that you are writing a class that tracks the number of Web page visitors. You wouldn’t want the visitor count to reset to zero every time the class is instantiated, and therefore you would set the field to be of the static scope: <?php class Visitor { private static $visitors = 0; Gilmore_862-8C06.fm Page 187 Tuesday, February 12, 2008 9:12 AM 188 CHAPTER 6 ■ OBJECT-ORIENTED PHP function __construct() { self::$visitors++; } static function getVisitors() { return self::$visitors; } } /* Instantiate the Visitor class. */ $visits = new Visitor(); echo Visitor::getVisitors()."<br />"; /* Instantiate another Visitor class. */ $visits2 = new Visitor(); echo Visitor::getVisitors()."<br />"; ?> The results are as follows: 1 2 Because the $visitors field was declared as static, any changes made to its value (in this case via the class constructor) are reflected across all instantiated objects. Also note that static fields and methods are referred to using the self keyword and class name, rather than via $this and arrow operators. This is because referring to static fields using the means allowed for their “regular” siblings is not possible and will result in a syntax error if attempted. ■Note You can’t use $this within a class to refer to a field declared as static. Gilmore_862-8C06.fm Page 188 Tuesday, February 12, 2008 9:12 AM CHAPTER 6 ■ OBJECT-ORIENTED PHP 189 The instanceof Keyword The instanceof keyword was introduced with PHP 5. With it you can determine whether an object is an instance of a class, is a subclass of a class, or implements a particular interface, and do something accordingly. For example, suppose you want to learn whether an object called manager is derived from the class Employee: $manager = new Employee(); if ($manager instanceof Employee) echo "Yes"; There are two points worth noting here. First, the class name is not surrounded by any sort of delimiters (quotes). Including them will result in a syntax error. Second, if this comparison fails, the script will abort execution. The instanceof keyword is particularly useful when you’re working with a number of objects simultaneously. For example, you might be repeatedly calling a particular function but want to tweak that function’s behavior in accordance with a given type of object. You might use a case statement and the instanceof keyword to manage behavior in this fashion. Helper Functions A number of functions are available to help the developer manage and use class libraries. These functions are introduced in this section. Determining Whether a Class Exists The class_exists() function returns TRUE if the class specified by class_name exists within the currently executing script context, and returns FALSE otherwise. Its proto- type follows: boolean class_exists(string class_name) Determining Object Context The get_class() function returns the name of the class to which object belongs and returns FALSE if object is not an object. Its prototype follows: string get_class(object object) Gilmore_862-8C06.fm Page 189 Tuesday, February 12, 2008 9:12 AM 190 CHAPTER 6 ■ OBJECT-ORIENTED PHP Learning About Class Methods The get_class_methods() function returns an array containing all method names defined by the class class_name. Its prototype follows: array get_class_methods(mixed class_name) Learning About Class Fields The get_class_vars() function returns an associative array containing the names of all fields and their corresponding values defined within the class specified by class_name. Its prototype follows: array get_class_vars(string class_name) Learning About Declared Classes The function get_declared_classes() returns an array containing the names of all classes defined within the currently executing script. The output of this function will vary according to how your PHP distribution is configured. For instance, executing get_declared_classes() on a test server produces a list of 97 classes. Its prototype follows: array get_declared_classes(void) Learning About Object Fields The function get_object_vars() returns an associative array containing the defined fields available to object and their corresponding values. Those fields that don’t possess a value will be assigned NULL within the associative array. Its prototype follows: array get_object_vars(object object) Determining an Object’s Parent Class The get_parent_class() function returns the name of the parent of the class to which object belongs. If object’s class is a base class, that class name will be returned. Its prototype follows: string get_parent_class(mixed object) Gilmore_862-8C06.fm Page 190 Tuesday, February 12, 2008 9:12 AM [...]... how to log messages to both your operating system syslog and a custom log file Exception handling: Prevalent among many popular languages (Java, C#, and Python, to name a few), exception handling was added to PHP with the version 5 release Exception handling offers a standardized process for detecting, responding to, and reporting errors 2 13 Gilmore_862-8.book Page 214 Tuesday, January 29, 2008 11 :37 ... you to better understand many of the key OOP concepts and inspire you to perform additional experimentation and research The next chapter introduces yet another new, and certainly long-awaited, feature of PHP 5: exception handling 211 Gilmore_862-8C07.fm Page 212 Tuesday, February 12, 2008 9: 13 AM Gilmore_862-8.book Page 2 13 Tuesday, January 29, 2008 11 :37 AM CHAPTER 8 ■■■ Error and Exception Handling... continued the search up to the Employee class, at which point it located an appropriate constructor If PHP had located a constructor in the Employee class, then it would have fired If you want both the Employee and Executive constructors to fire, you need to place a call to parent:: construct() in the Executive constructor You also have the option to reference parent constructors in another fashion... Also Rises Be sure to consult the PHP manual before implementing PHP 6’s namespace feature into your own applications, as the capabilities and constraints are likely to change significantly following this book’s publication Summary This and the previous chapter introduced you to the entire gamut of PHP s OOP features, both old and new Although the PHP development team was careful to ensure that users... Library.inc .php and place this line at the top: namespace Library; Likewise, open DataCleaner.inc .php and place the following line at the top: namespace DataCleaner; You can then begin using the respective Clean classes without fear of name clashes To do so, instantiate each class by prefixing it with the namespace, as demonstrated in the following example: < ?php include "Library .php" ; include "Data .php" ;... Because Executive has inherited from Employee, objects of type CEO also have all the members and methods that are available to Executive, in addition to the getFacelift() method, which is reserved solely for objects of type CEO Inheritance and Constructors A common question pertinent to class inheritance has to do with the use of constructors Does a parent class constructor execute when a child is instantiated?... wouldn’t be fair to allow outside contractors to pillage the company; after all, it was upon the backs of the full-time employees that the organization was built That said, how can you provide employees with the ability to both do their jobs and pillage the company, while limiting contractors solely to the tasks required of them? The solution is to break these tasks down into several tasks and then implement... must be able to encounter and react to such unexpected errors in a graceful fashion, hopefully doing so without losing data or crashing the application In addition, your application should be able to provide users with the feedback necessary to understand the reason for such errors and potentially adjust their behavior accordingly This chapter introduces several features PHP has to offer for handling errors... time and the PHP 6 release To illustrate the challenge, suppose you’ve created a Web site that enables you to organize your book collection, and allows visitors to comment on any books found in your personal library To manage comments, you’ve created a library called Library inc .php, which includes a class named Clean This class implements a variety of general data filters that you could apply to not... 12, 2008 9: 13 AM 210 CHAPTER 7 ■ ADVA NC ED OOP FEATURES Fatal error: Cannot redeclare class Clean You’re receiving this error because it’s not possible to use two classes of the same name within the same script Starting with PHP 6, there’s a simple way to resolve this issue by using namespaces All you need to do is assign a namespace to each class To do so, you need to make one modification to each file . methods, called construc- tors and destructors, that automate the object creation and destruction processes. Constructors You often want to initialize certain fields and even trigger the execution. visitors. You wouldn’t want the visitor count to reset to zero every time the class is instantiated, and therefore you would set the field to be of the static scope: < ?php class Visitor . upon script completion in PHP 4, it wasn’t possible to customize this cleanup process. With the introduction of destruc- tors in PHP 5, this constraint is no more. Destructors are created like any