[ Team LiB ] Previous Section Next Section

Objects and Constants

In Hour 4, "The Building Blocks," we looked at defining global constants. Remember that constants hold values that cannot be changed during script execution. You define global constants using the define() function.

As of PHP 5, you can define constants within classes. You declare a constant using the const keyword at the top of your class:


class MyClass {
        const PI = 3.14;
//...

Constants are available via the class rather than an object:


print MyClass::PI;

This aspect makes a class constant useful when the value it contains applies equally to all objects of the type and when the value should be fixed and unchangeable.

Let's work through a simple example. In Listing 17.1, we present a fragment of an Item class. An Item in this example is an item of stock in a shop. We want to store an integer $status property for every Item. This single integer will combine multiple flags. We want the flags to be available globally, and we need them to be read-only.

Listing 17.1 A Class That Uses Class Constants
 1: <?php
 2:
 3: class Item {
 4:   const DISCONTINUED = 1;
 5:   const PROMOTIONAL = 2;
 6:   const STOCKED_OFFSITE = 4;
 7:   private $status = 0;
 8:
 9:   public function addStatus( $num ) {
10:     $this->status | = $num;
11:   }
12:
13:   public function isPromotional() {
14:     return ( Item::PROMOTIONAL & $this->status )?true:false;
15:   }
16:
17:   public function isDiscontinued() {
18:     return ( Item::DISCONTINUED & $this->status )?true:false;
19:   }
20:
21:   public function isOffsiteItem() {
22:     return ( Item::STOCKED_OFFSITE & $this->status )?true:false;
23:   }
24: }
25:
26: $item = new Item();
27: $item->addStatus( Item::STOCKED_OFFSITE );
28: $item->addStatus( Item::PROMOTIONAL );
29: $item->addStatus( Item::DISCONTINUED );
30:
31: if ( $item->isOffsiteItem() ) {
32:   print "This item is stocked at our warehouse. Delivery within 4 days";
33: }
34: ?>

We define three class constant flags on lines 4 to 6. It's easiest to think of these flags in binary terms:


001 = 1
010 = 2
100 = 4

The idea is that we can combine each of those numbers in a single $status property by using the binary or (|) operator. This process sets the bits that are set in either one operand or the other:


1  | 2  ==   3
001 or 010 equals 011

We perform the operation to combine flags in the addStatus() method on line 9. We call addStatus() on lines 27 to 29, setting all the available bits. Notice how we access the status flags using the class name and not the object handle.

The rest of the class consists of methods to check the $status array. Let's look at isDiscontinued() on line 17. We use the binary and (&) operator to compare $status with the constant flag Item::DISCONTINUED. This test compares the bits in the two operands and resolves to a new number that contains only the bits that the two numbers have in common:


111  $status
001  DISCONTINUED
001  result of 'and' operation

The effect of this operation is that isDiscontinued() will only return true if Item::DISCONTINUED has been passed to addStatus().

Another common use for class constants is to store error codes that can be set and tested when an object fails in an operation.

    [ Team LiB ] Previous Section Next Section