Monday, September 13, 2010

PHP - Visibility (public, private, protected)

Visibility (public, private, protected)

The visibility of class members, (properties, methods), relates to how that member may be manipulated within, or from outside the class. Three levels of visibilty exist for class members.
  • public
  • private
  • protected
By default, all class members are public. This means if you do not declare a property or method within the class, it will be public. It is good practice to declare the visibility of class members for the sake of readability for yourself and others. It is much easier for another programmer to see your intentions. This will also future proof your scripts should access modifiers be deprecated.
Public class members (properties and methods) are available through-out the script and may be accessed from outside the class as we demonstrated in our car class. Lets create a simple new class to demonstrate.


class mathematics{/*** a  number ***/public $num;
/**
*
* Add two to a number
*
* @access public
*
* @return int
*
**/
public function addTwo(){
  return 
$this->num+2;
}

}
/*** end of class ***/

/*** Instantiate a new class instance ***/
$math = new mathematics;
/*** set the value of the number ***/$math->num = 2;
/*** call the addTwo method ***/echo $math->addTwo();
?>
We can see in the above example that the public variable $num is set from user space and we call a public method that adds two the number and returns the value of $num+2. Having our properties (variables) visible, or accessible from any part of our script works in our favour here, but it can also work against us. A could arise if we lost track of our values and changed the value of $num. To counter this problem we can create a method to set the value for us. Even with this in place it is still possible for somebody to simply access the $num variable. So we make the variable private. This ensures us that the property is only available within the class itself. It is private to the calling class. Consider the following code.



class mathematics{
/*** a  number ***/private $num;
/**
*
* Set the value of $num
*
* @access public
*
* @param $num The number to set
*
* @return int
*
**/
public function setNum($num){
  
$this->num = $num;
}
/**
*
* Add two to a number
*
* @access public
*
* @return int
*
**/
public function addTwo(){
  return 
$this->num+2;
}

}
/*** end of class ***/

/*** Instantiate a new class instance ***/
$math = new mathematics;
/*** set the value of the number ***/$math->setNum(2);
/*** call the addTwo method ***/echo $math->addTwo();
?>
?>
Any further attempt to reset the $num property without the setNum() method would result in a Fatal Error such as
Fatal error: Cannot access private property mathematics::$num in /www/mathematics.class.php on line 43
Even if you were to try to access the private $num property from a child class it would fail. This is because private methods and properties in a parent class are not visible to child classes and cannot be accessed. To access a parent method or property from a child class you need to use the protected keyword. Like the private keyword, protetected methods and properties are available only to the class that created them. But unlike private, protected methods and properties are visible from a parent class. Lets see how this works.

class mathematics{/*** a  number ***/protected $num;
/**
*
* Set the value of $num
*
* @access public
*
* @param $num The number to set
*
* @return int
*
**/
public function setNum($num){
  
$this->num = $num;
}
/**
*
* Add two to a number
*
* @access public
*
* @return int
*
**/
public function addTwo(){
  return 
$this->num+2;
}

}
/*** end of class ***/
class divide extends mathematics{
/**
*
* Divide a number by two
*
* @access public
*
* @return int
*
**/
public function divideByTwo(){
  
/*** divide number by two ***/
  
$new_num = $this->num/2;
  
/*** return the new number and round to 2 decimal places ***/
  
return round($new_num, 2);
}

} 
/*** end of class ***/

/*** Instantiate a new class instance ***/
$math = new divide;
/*** set the value of the number ***/$math->setNum(14);

echo 
$math->divideByTwo();
?>
We can see here the the user space code has called the setNum() method in the parent mathematics class. This method, in turn, sets the $num property. We are able to do this because the $num property has been declared protected and is visible to the child class.

Final

As we saw in the previous section there are ways to protect your code from being used in an improper manner. Another way of protecting yourself is the Final keyword. Any method or class that is declared as Final cannot be overridden or inherited by another class. Lets put it to the test.

final class mathematics{

} 
/*** end of class ***/
class divide extends mathematics{

}
?>
By running the above code you will get an error such as
Fatal error: Class divide may not inherit from final class (mathematics) in /www/final.php on line 8
This can protect us from those who wish to use our code for a purpose other than that for which it was intended.

Abstract Classes

An abstract class is a class that cannot be instantiated on its own. You cannot create a new object from it. To see this lets make a basic class.

abstract class mathematics{
/**
*
* Add two to a number
*
* @access public
*
* @return int
*
**/
public function addTwo(){
  return 
$this->num+2;
}

} 
/*** end of class ***/

/*** try to create new object from the mathematics class ***/
$math = new mathematics

?>
Using the code above, you will get an error something like this
Fatal error: Cannot instantiate abstract class mathematics in /www/abstract.php on line 23.
As you can see, this is not allowed. Also if you declare any class method to be abstract, you must also declare the class itself as abstract too. So, whats the point you ask? Well, you can inherit from an abstract class. Any class that extends an abstract parent class must create an interface of the parent abstract methods. If this is not done a fatal error is generated. This ensures that the implementation is correct.

abstract class mathematics{/*** child class must define these methods ***/abstract protected function getMessage();

abstract protected function 
addTwo($num1);
/**
*
* method common to both classes
*
**/
public function showMessage() {
  echo 
$this->getMessage();
}

} 
/*** end of class ***/
class myMath extends mathematics{/**
*
* Prefix to the answer
*
* @return string
*
**/
protected function getMessage(){
  return 
"The anwser is: ";
}
/**
*
* add two to a number
*
* @access public
*
* @param $num1 A number to be added to
*
* @return int
*
**/
public function addTwo($num1) {
  return 
$num1+2;
}

} 
/*** end of class ***/

/*** a new instance of myMath ***/
$myMath = new myMath;/*** show the message ***/$myMath->showMessage();/*** do the math ***/echo $myMath->addTwo(4);
?>

Static Methods and Properties

The use of the static keyword allows class members (methods and properties) to be used without needing to instantiate a new instance of the class. The static declaratin must come after the visibility declaration, eg:
public static myClass{
Because there is no object created when using a static call, the keyword $this and the arrow operator, -> are not available. Static variables belong to the class itself and not to any object of that class. To access withing the class itself you need to use the self keyword along with the :: scope resolution operator. Lets whip up a quick example of using static.
/*** a simple class ***/class myClass{/*** a static variable ***/ static $foo;
}
/** give the static variable a value ***/myClass::$foo = 'Bar';
/*** echo the static variable ***/echo (myClass::$foo ).?>
The above snippet will echo
Bar This is rather basic as an example, so lets use something practical. Static properties are often used as counters. Here we will use a basic counter class.
class counter{
/*** our count variable ***/private static $count = 0;
/**
* Constructor, duh
**/
function __construct() {
  
self::$count++;
}
/**
*
* get the current count
*
* @access public
*
* @return int
*
**/
public static function getCount() {
 return 
self::$count;
}

} 
/*** end of class ***/

/*** create a new instance ***/
$count = new counter(); /*** get the count ***/echo counter::getCount() . '';/*** create another instance ***/$next = new counter(); /*** echo the new count ***/echo counter::getCount().''; /*** and a third instance ***/$third = new counter;
echo 
counter::getCount().'';?>
Hopefully by the end of the above snippet you can see what is happening. At each new instance the counter class we increment by one. Not also the use of the :: scope resolution operator and self keyword to refer to the static variable within the class itself.

Interfaces

Interfaces in PHP allow you to define a common structure for your classes. An interface cannot be instantiated on its own. One of the goals of OOP is re-use of code. Interfaces make this a much easier process. The interface methods have no internal logic, they are simply a "mapping" or constraint of what the class, or classes, should implement. Here we will demonstrate how this works using our vehicle class from earlier, with the addition of a stop() function.
class vehicle implements testdrive{
/*** define public properties ***/

/*** the color of the vehicle ***/
public $color;
/*** the number of doors ***/public $num_doors;
/*** the price of the vehicle ***/public $price;
/*** the shape of the vehicle ***/public $shape;
/*** the brand of vehicle ***/public $brand;
/*** the constructor ***/public function __construct(){
  echo 
'About this Vehicle.';
}
/*** define some public methods ***/

/*** a method to show the vehicle price ***/
public function showPrice(){
  echo 
'This vehicle costs '.$this->price.'.';
}
/*** a method to show the number of doors ***/public function numDoors(){
  echo 
'This vehicle has '.$this->num_doors.' doors.';
}
/*** method to drive the vehicle ***/public function drive(){
  echo 
'VRRROOOOOOM!!!';
}
/**
* a method to stop the car
*
* @access public
*
**/
public function stop(){
  echo 
'SSSCCRRREEEEEECCHH!!!';
}

} 
/*** end of class ***/

/*** declare our interface ***/
interface testdrive{/*** some functions that must be implemented ***/function drive();
function 
stop();
}
/*** an new vehicle object ***/$object = new vehicle;
/*** call some methods ***/$object->drive();$object->stop();?>
You may of course create multiple classes to implement your interface, but they will not inherit from each other. When you inherit from a parent class, you may choose to override some of parent methods. If you had multiple parent class methods with the same name, but different functionality or charactaristics, PHP would have no way of telling which of these methods to use. This is why multiple inheritance does not work in PHP. In contrast, classes that implement an interface, must implement every method so there is no ambiguity.
In the real world interfaces provide us with the tools harness parts of multiple classes. Consider this scenario. If we had two classes, one for a fax and the other for a printer. Each has seperate uses and could be described like this:

class fax{
  public function 
dial();
  public function 
send();
  public function 
recieve();
}

class 
printer{
  public function 
printBlack();
  public function 
printColor();
  public function 
printDraft();
}
?>
Both of the above classes give the required usage for each item, but they do not take into consideration the existance of a printer/fax machine. To get the usage of both classes we would do something like this:

class fax{
  public function 
dial();
  public function 
send();
  public function 
recieve();
}

class 
printer extends fax{
  public function 
printBlack();
  public function 
printColor();
  public function 
printDraft();
  public function 
kick();
}

class 
printerFax extends fax{
}
$object = new printerFax;?>
This code works by creating a stack of classes. The grandparent class is fax. Then the printer class extends the fax class and inherits all the methods from that class. This is where some problems may arise. The printer class now has the function dial() available to it which is clearly going to cause some confusion and possibly errors in logic.
To counter this problem an interface can be used to tell the classes what functions (methods) are required. Lets look at the design.

interface fax{
  public function 
dial();
  public function 
send();
  public function 
recieve();
}

interface 
printer{
  public function 
printBlack();
  public function 
printColor();
  public function 
printDraft();
  public function 
kick();
}

class 
printerFax implements fax, printer{
  public function 
dial(){ }
  public function 
send(){ }
  public function 
recieve(){ }
  public function 
printBlack(){ }
  public function 
printColor(){ }
  public function 
printDraft(){ }
  public function 
kick(){ }
}

  
$object = new printerFax;?>
Before we go further, it is recommended you run the above code. It will produce no output but we need to be sure all is well. Having run the code, remove the line
public function kick(){ }
and run it again. What you should now get is an error such as:
Fatal error: Class printerFax contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (printer::kick) in /www/oop.php on line 22
With the kick() function removed from our implementation, we have essentially broken the contract that says we will implement every function (method) specified in the interface. We can gather these functions fractionally from multiple classes, but we MUST have them all or we will get errors such as the one above.
Interfaces play a major role in with SPL and it is recommend you implement the interfaces from SPL and not just the class methods.

PHP 5 with OOPs

What is OOP

OOP was first invented for the purpose of physical modelling in the Simula-67.
Whilst there is no hard and fast definition of what Object Oriented Programming (OOP) is, we can define. So lets just use this loose definition for now and it is left to reader to make up their own minds about what a decent definition is. Object Oriented Programming (OOP) is a programming concept that treats functions and data as objects. OK, not the best definition but gives us an opening. The key word here is objects. As we progress through this tutorial we will see how data and functions can be represented as re-usable objects, thus cutting down on code and time.

What is an Object

Simply put, an oject is a bunch of variables and functions all lumped into a single entity. The object can then be called rather than calling the variables or functions themselves. Within an object there are methods and properties. The methods are functions that manipulate data withing the object. The properties are variables that hold information about the object.

What is a Class

A class is the blueprint for your object. The class contains the methods and properties, or the charactaristics of the object. It defines the object. Lets just start with some examples to see how it all pieces together. We will use a vehicle as our object. All vehicles share similar charactaristics, eg: number of doors, they are painted some color, they each have a price. All vehicles do similar things also, drive, turn left, turn right, stop etc. These can be described as functions, or in OOP parlance, methods. So, the class holds the definition, and the object holds the value. You declare class in PHP by using the class keyword.
class vehicle{/*** define public properties ***/

/*** the color of the vehicle ***/
public $color;
/*** the number of doors ***/public $num_doors;
/*** the price of the vehicle ***/public $price;
/*** the shape of the vehicle ***/public $shape;
/*** the brand of vehicle ***/public $brand;
/*** the constructor ***/public function __construct(){
  echo 
'About this Vehicle.';
}
/*** define some public methods ***/

/*** a method to show the vehicle price ***/
public function showPrice(){
  echo 
'This vehicle costs '.$this->price.'.';
}
/*** a method to show the number of doors ***/public function numDoors(){
  echo 
'This vehicle has '.$this->num_doors.' doors.';
}
/*** method to drive the vehicle ***/public function drive(){
  echo 
'VRRROOOOOOM!!!';
}

} 
/*** end of class ***/?>

With this simple class definition we can now create one, or many, vehicle objects. Lets see how its done, then we will step through it all. To create a new object from the class definition we use the new keyword.

/*** create a new vehicle object ***/$vehicle = new vehicle;
/*** the brand of vehicle ***/$vehicle->brand = 'Porsche';
/*** the shape of vehicle ***/$vehicle->shape = 'Coupe';
/*** the color of the vehicle ***/$vehicle->color = 'Red';
/*** number of doors ***/$vehicle->num_doors = 2;
/*** cost of the vehicle ***/$vehicle->price = 100000;
/*** call the showPrice method ***/$vehicle->showPrice();
/*** call the numDoors method ***/$vehicle->numDoors();
/*** drive the vehicle ***/$vehicle->drive();
?>
Using the combination of the two code boxes above, you should have something like..
About this vehicle.
This vehicle costs 100000.
This vehicle has 2 doors.
Lets step through the class definition first to see what its all about.
We began the class with the class keyword. This tells PHP that what follows is a class definition.

class vehicle{
?>
Next we declared some variables, or as they are known in the OOP world, properties.

/*** the color of the vehicle ***/public $color;
/*** the number of doors ***/public $num_doors;
/*** the price of the vehicle ***/public $price;
/*** the shape of the vehicle ***/public $shape;
/*** the brand of vehicle ***/public $brand;
?>
The properties are the individual charactaristics of the vehicle object. The public declares that this property may be accessed within the public scope. This means you may set it from within your code. Next in the class definition is this code..

/*** the constructor ***/public function __construct(){
  echo 
'About this vehicle.';
}
?>
The constructor method (function) is a special function that is executed every time a new object is created or "instantiated". If a class needs to do something before running some code, then this is the place to do it. It is often used to set properties within the class. You may pass a variable directly to the constructor from your code, but more of that later. Following the constructor is several methods (functions) that do things. These methods are also preceded by the public meaning they are available with the scope of your code.

/*** a method to show the vehicle price ***/public function showPrice(){
  echo 
'This vehicle costs '.$this->price.'.';
}
/*** a method to show the number of doors ***/public function numDoors(){
  echo 
'This vehicle has '.$this->num_doors.' doors.';
}
/*** method to drive the vehicle ***/public function drive(){
  echo 
'VRRROOOOOOM';
}
?>
As you see above, our methods are similar to normal PHP functions. However you may note the use of variables like $this->price and $this->num_doors. The keyword $this is used to refer to properties or methods within the class itself. The $this keyword is reserved in PHP, so it cannot be used as a variable or property name. Finally we finished our class definition with a closing }. I like to put a comment beside it so I dont delete it or get it confused with a function I am writing.
Following on from the class definition we see our userland code. This is the code we use to instantiate (create) a new instance, or new object, of our vehicle class. As mentioned earlier we do this with the use of the new keyword.

/*** create a new vehicle object ***/$vehicle = new vehicle;
?>
The code above creates a new object from our class definition called $vehicle. It is at this time that the constructor is called and any code within the constructor is executed. Once we have a new object we can then begin to assign values to the properties of that object as seen here.

/*** the brand of vehicle ***/$vehicle->brand = 'Porsche';
/*** the shape of vehicle ***/$vehicle->shape = 'Coupe';
/*** the color of the vehicle ***/$vehicle->color = 'Red';
/*** number of doors ***/$vehicle->num_doors = 2;
?>
With the properties set as above, it is now simple to use the object methods to manipulate the object by calling the methods. The methods are executed like this below.
/*** call the showPrice method ***/$vehicle->showPrice();
/*** call the numDoors method ***/$vehicle->numDoors();
/*** drive the vehicle ***/$vehicle->drive();?>
So, thats the step-by-step of your first class. You see how easy it would be now to create a new car object. Perhaps a Red Ferrari with 4 doors costing $250,000.00.

Commenting Code

In the previous sections you have seen comments for almost every line of code. This is a good practice, although some may find it excessive, as it may not be you who has to edit the code next time. OOP can get very abstracted and if you are not careful it is easy to lose site of your programmatical work flow. Most methods within a class will return a value, rather than echo a line of HTML code. A class method may also take one, or several, arguements. It is good practice to show what these arguements are and there types. An example follows below.
  /**
  * adds an array of numbers and returns the value
  *
  * @param array $numbers An array of numbers to add
  *
  * @access private
  *
  * @return int Returns sum of numbers
  *
  */
  
private function sum_of_numbers($numbers){
    
/*** return the sum of the $numbers array ***/
    
return array_sum($numbers);
  }
?>
The above function is rather simplistic, but shows well the commenting of code. The comments begin in a block of C type multiline comments and gives us a brief description of what it does, followed by the parameter it takes, in this case an array of numbers. It tells us that access to the function is private (more on this in the next section). Finally the comment block tells us that the return value is of type INT. We can also see within the function itself a single line comment just to show what is happening within the funtion itself. If you follow these practices you code will always be readable and easy to follow by yourself and others.

Inheritance (Extending a class)

Probably the greatest feature of the PHP OOP model is Inheritence. Inheritence is the ability of php to extend classes (child classes) that inherit the charactaristics of the parent class. The resulting object of an extend class has all the charactaristics of the parent class, plus whatever is in the new child, or extended class. In this instance we will extend the vehicle class and add a motorcyle. A motorcycle is still a vehicle and shares many of the same attributes such as price, drive etc. But a motorcycle has some unique features that a car does not.
Rather than type out the whole of the vehicle class definition again, we will save it in a file of its own called vehicle.class.php. It is important here to note the naming convention here as it will be important later in this tutorial. Lets see how it works.



/*** include the vehicle class definition ***/include('vehicle.class.php');

class 
motorcycle extends vehicle{
/*** the number of side cars ***/private $num_sidecars;

private 
$handlebars;
/**
*
* set the type of handlebars
*
* @access public
*
* @param string
*
* @return string
*
**/
public function setHandlebars($handlebarType){
  
$this->handlebars=$handlebarType;
}
/**
*
* Set number of side cars
*
* @access public
*
* @param int
*
* @return int
*
**/
public function setSidecar($numSidecars){
  
$this->numSidecars = $numSidecars;
}

/**
*
* Show the numbers of sidecars
*
* @return string
*
**/
public function showSideCar(){
  echo 
'This motorcyle has '. $this->numSidecars.' sidecar';
}

} 
/*** end of class ***/


/*** our userland code ***/

/*** create a new vehicle object ***/
$vehicle = new motorcycle;
/*** the brand of vehicle ***/$vehicle->brand = 'Harley Davidson';
/*** the shape of vehicle ***/$vehicle->shape = 'Sportster';
/*** the color of the vehicle ***/$vehicle->color = 'Black';
/*** number of doors ***/$vehicle->num_doors = 0;
/*** cost of the vehicle ***/$vehicle->price = 25000;
/*** type of handle bars ***/$vehicle->setHandlebars('Ape Hangers');
/*** set the sidecar ***/$vehicle->setSidecar(1);
/*** show the vehicle brand and type ***/echo $vehicle->brand.': '.$vehicle->shape.'';

/*** call the showPrice method ***/$vehicle->showPrice();
/*** show the sidecars ***/$vehicle->showSideCar();
/*** drive the vehicle ***/$vehicle->drive();
?>
You see in the motorcycle class that we have used the keyword extends to extend our vehicle class. We can then proceed to set vars in the both the parent class and the child class. The child class has inherited all the characaristics of the parent vehicle class.
If you run the above code with out including the parent class, you will get a Fatal Error like this:
Fatal error: Class 'vehicle' not found in /www/oop.php on line 3

You MUST include the class definition on *every page* when you store an object
This means when you use an object or wish to extend from it. you must include the class file. Either as code, or most commonly, with an include() statement.
 

Wednesday, September 8, 2010

New features in PHP 6

As you may be aware the core PHP group of developers all met in Paris on November the 11th and 12th 2005. The minutes from the meeting are fascinating reading, but there is a lot to go through. So I've gone through all of the points raised and chewed them over from a developers point of view. Your comments as always are welcome.
Before I get started however I'd just like to make one thing very clear: what you read here (or in the original minutes) are in no way the 'fully 100% decided' end results / changes that we'll see in PHP6. They will most likely all be discussed further (on internals and wider), but even so we can take the information presented in the minutes as being the PHP teams most 'current' way of thinking about any given subject.

Unicode

Unicode support at present can be set on a per request basis. This equates to PHP having to store both Unicode and non-Unicode variants of class, method and function names in the symbol tables. In short - it uses up more resources. Their decision is to make the Unicode setting server wide, not request wide. Turning Unicode off where not required can help performance and they quote some string functions as being up to 300% slower and whole applications 25% slower as a result. The decision to move it to the php.ini in my mind does take the control away from the user, and puts it into the hands of the Web Host.
If you compile PHP yourself or are responsible for this on your servers then you may be interested to know that PHP 6 will require the ICU libs (regardless if Unicode is turned on or off). The build system will bail out if the required ICU libs cannot be found. In a nutshell, you'll have another thing to install if you want to compile PHP.

Register Globals to go

Say goodbye folks, this one is finally going. It will no longer be an ini file setting, and if found it will raise an E_CORE_ERROR, pointing you to the documentation on why it's "bad". This means that PHP6 will finally break all PHP3 era scripts (or any script using reg globals) with no recourse at all but to re-code it. That's a bold move, but a needed one.

Magic Quotes to go

The magic quotes feature of PHP will be going, and as with register globals it's going to raise an E_CORE_ERROR if the setting is found anywhere. This will affect magic_quotes, magic_quotes_sybase and magic_quotes_gpc.

Safe Mode to go

This may please developers who have web hosts that insist upon safe mode! But it will now go totally, again raising an E_CORE_ERROR if found. The reason is that apparently they felt it gave the 'wrong signal', implying that it made PHP secure, when infact it didn't at all. open_basedir will (thankfully) be kept.

'var' to alias 'public'

PHP4 used 'var' within classes. PHP5 (in its OO move) caused this to raise a warning under E_STRICT. This warning will be removed in PHP6 and instead 'var' will mean the same thing as 'public'. This is a nice move but I if anyone has updated their scripts to work under E_STRICT in PHP5 it will be a redundant one for them.

Return by Reference will error

Both '$foo =& new StdClass()' and 'function &foo' will now raise an E_STRICT error.

zend.ze1 compatbility mode to go

ze1 always tried to retain old PHP4 behaviour, but apparently it "doesn't work 100%" anyway, so it will be removed totally and throw an E_CORE_ERROR if detected.

Freetype 1 and GD 1 support to go

Support for both of these (very very old) libs will be removed.

dl() moves to SAPI only

Each SAPI will register the use of this function as required, only the CLI and embed SAPIs will do this from now on. It will not be available elsewhere.

FastCGI always on

The FastCGI code will be cleaned up and always enabled for the CGI SAPI, it will not be able to be disabled.

Register Long Arrays to go

Remember the HTTP_*_VARS globals from yesteryear? Well if you're not already using $_GET, $_POST, etc - start doing so now, because the option to enable long arrays is going (and will throw an E_CORE_ERROR).

Extension Movements

The XMLReader and XMLWriter extensions will move into the core distribution and will be on by default.
The ereg extension will move to PECL (and thus be removed from PHP). This means that PCRE will not be allowed to be disabled. This will make way for the new regular expression extension based on ICU.
The extremely useful Fileinfo exntesion will move into the core distribution and enabled by default.

PHP Engine Additions

64 bit integers
A new 64 bit integer will be added (int64). There will be no int32 (it is assumed unless you specify int64)
Goto
No 'goto' command will be added, but the break keyword will be extended with a static label - so you could do 'break foo' and it'll jump to the label foo: in your code.
ifsetor()
It looks like we won't be seeing this one, which is a shame. But instead the ?: operator will have the 'middle parameter' requirement dropped, which means you'd be able to do something like this: "$foo = $_GET['foo'] ?: 42;" (i.e. if foo is true, $foo will equal 42). This should save some code, but I personally don't think it is as 'readable' as ifsetor would have been.
foreach multi-dim arrays
This is a nice change - you'll be able to foreach through array lists, i.e. "foreach( $a as $k => list($a, $b))".
{} vs []
You can currently use both {} and [] to access string indexes. But the {} notation will raise an E_STRICT in PHP5.1 and will be gone totally in PHP6. Also the [] version will gain substr and array_slice functionality directly - so you could do "[2,]" to access characters 2 to the end, etc. Very handy.

OO changes

Static Binding
A new keyword will be created to allow for late static binding - static::static2(), this will perform runtime evaluation of statics.
Namespaces
It looks like this one is still undecided - if they do implement namespaces it will be using their style only. My advice? Don't hold your breath!
Type-hinted Return Values
Although they decided against allowing type-hinted properties (becaue it's "not the PHP way") they will add support for type-hinted return values, but have yet to decide on a syntax for this. Even so, it will be a nice addition.
Calling dynamic functions as static will E_FATAL
At the moment you can call both static and dynamic methods, whether they are static or not. Calling a dynamic function with the static call syntax will raise an E_FATAL.

Additions to PHP

APC to be in the core distribution
The opcode cache APC will be included in the core distribution of PHP as standard, it will not however be turned on by default (but having it there saves the compilation of yet another thing on your server, and web hosts are more likely to allow it to be enabled)
Hardened PHP patch
This patch implements a bunch of extra security checks in PHP. They went over it and the following changes will now take place within PHP: Protection against HTTP Response Splitting will be included. allow_url_fopen will be split into two: allow_url_fopen and allow_url_include. allow_url_fopen will be enabled by default. allow_url_include will be disabled by default.
E_STRICT merges into E_ALL
Wow, this is quite a serious one! E_STRICT level messages will be added to E_ALL by default. This shows a marked move by the PHP team to educate developers on 'best practises' and displaying language-level warnings in a "Hey, you're doing it the wrong way".
Farewell <%
They will remove support for the ASP style tags, but the PHP short-code tag will remain (

Conclusion

PHP6 is taking an interesting move in my mind - it's as if the PHP developers want to now educate developers about the right way to code something, and remove those lingering issues with "Well you SHOULD be doing it this way, but you can still do it the old way". This will not be the case any longer. Removing totally the likes of register globals, magic quotes, long arrays, {} string indexes and call-time-pass-by-references will force developers to clean up their code.
It will also break a crapload of scripts beyond repair that doesn't involve some serious re-writing. Is this a bad thing? I don't think so myself, but I see it making the adoption of PHP6 even slower than that of PHP5, which is a real shame. However they have to leap this hurdle at some point, and once they've done it progression to future versions should be swifter.

Saturday, September 4, 2010

Add mrtg to nagios

Mrtg software may install during initial installation; you can verify if MRTG installed or not with following RPM command:
rpm -qa | grep mrtg
If mrtg already installed please see

step # 5; else use rpmfind.net to find MRTG rpm or up2date command to install MRTG software:
# up2date -v -i mrtg
Fedora Linux user can use yum command as follows to install MRTG:
# yum install mrtg

Step # 5 : Commands to Configure mrtg

(a) Create document root to store mrtg graphs/html pages:
# mkdir -p /var/www/html/mymrtg/
(b) Run any one of the following cfgmaker command to create mrtg configuration file:
#cfgmaker --global 'WorkDir: /var/www/html/mymrtg' --output /etc/mrtg/mymrtg.cfg public@localhost
OR (make sure your FQDN resolves, in following example i'm using rh9.test.com which is my router FQDN address)
# cfgmaker --global 'WorkDir: /var/www/html/mymrtg' --output /etc/mrtg/mymrtg1.cfg public@rh9.test.com
(c) Create default index page for your MRTG configuration:
# indexmaker --output=/var/www/html/mymrtg/index.html /etc/mrtg/mymrtg.cfg
(d) Copy all tiny png files to your mrtg path:
# cp -av /var/www/html/mrtg/*.png /var/www/html/mymrtg/
Run mrtg command from command line with your configuration file:
# mrtg /etc/mrtg/mymrtg.cfg
Note: You may get few warning message for first time; ignore them.
(b) Fire your favorite web browser (like FireFox :D ) and type url http://www.your.com/mymrtg/ or http://your-ip/mymrtg/


******************************
Now Your MRTG is running fine. Integrate it to nagios
************************************
Procedure to monitor Bandwidth Usages in Nagios:



1. Default installation directory of nagios is /usr/local/nagios/.

2. Open switch.cfg file
vi /usr/local/nagios/etc/objects/switch.cfg

3. Make changes according to your router specifications. Like,
define host{
use generic-switch
host_name Router_1
alias Router 1
address 172.17.42.22
hostgroups switches
}
4. You can also set PING, Uptime, Ports Link Status etc.
define service{
use generic-service ; Inherit values from a template
host_name Router_1 ; The name of the host the service is associated with
service_description PING ; The service description
check_command check_ping!200.0,20%!600.0,60% ; The command used to monitor the service
normal_check_interval 5 ; Check the service every 5 minutes under normal conditions
retry_check_interval 1 ; Re-check the service every minute until its final/hard state is determined
}

define service{
use generic-service ; Inherit values from a template
host_name Router_1
service_description Uptime
check_command check_snmp!-C public -o sysUpTime.0 -H 172.17.42.22
}

define service{
use generic-service ; Inherit values from a template
host_name Router_1
service_description Port 2 Link Status
check_command check_snmp!-C public -o ifOperStatus.2 -r 1 -H 172.17.42.22
}

define service{
use generic-service ; Inherit values from a template
host_name Router_1
service_description Port 2 Bandwidth Usage
check_command check_local_mrtgtraf!/var/www/html/mrtg/172.17.42.22_2.log!AVG!1000000,1000000!5000000,5000000
!10
}

5. Verify the configuration of nagios
/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg

6. Restart nagios service.
/etc/init.d/nagios restart

Friday, September 3, 2010

Install and Enable SNMP Service in Windows XP, Vista and 2003

SNMP (Simple Network Management Protocol) is an internet protocol used in network management systems to monitor network-attached devices such as computers, servers, routers, switches, gateways, wireless access points, VoIP phones, and etc. for conditions that warrant administrative attention. SNMP provides management data in the form of variables on the managed systems, which describe the system configuration parameter or current status value. These variables can then be read and queried (or sometimes set or write) by managing applications. Windows system running XP, Vista or 2003 does not turn on SNMP service by default, thus users need to manually install and enable SNMP service.


Note that you must be logged on as an administrator or a member of the Administrators group in order to complete this procedure. If your computer is connected to a network, network policy settings may also prevent you from completing this procedure.

How to Install and Enable the SNMP Service

  1. In Windows XP and Windows 2003, click Start button, then go to Control Panel and run Add or Remove Programs applet. On Add or Remove Programs dialog, click Add/Remove Windows Components to open Windows Components wizard.

    In Windows Vista, click Start button, then go to Control Panel. Click on Programs link and then click on Turn Windows features on or off. If you’re prompted with User Account Control dialog, click “Continue”.

  2. In Components of Windows XP and 2003, click on the Management and Monitoring Tools (make sure that you do not select or clear, tick or untick its check box to change the existing selection), and then click Details.

    In Windows Features of Vista, locate SNMP feature.

  3. Select and tick the check box of Simple Network Management Protocol or SNMP feature.
  4. Click OK. Also click Next if you’re in Windows XP or 2003. SNMP service will be installed on the system. You may require to insert the Windows setup CD/DVD disc into optical drive.
  5. SNMP will start automatically after installation. But it’s recommended to verify the service status from Services in Control Panel, and if it’s stopped, you can start the SNMP service from there.

    Two new services will be created:

    1. SNMP Service which is the main engine with agents that monitor the activity in the network devices and report the information to the monitoring console workstation.
    2. SNMP Trap Service which receives trap messages generated by local or remote SNMP agents and forwards the messages to SNMP management programs running on this computer.

Windows doesn’t assign any community string to the SNMP service by default, and also only allow access from localhost or local devices. Further configuration is needed to add in desired community string, which act as the password to grant reply to any SNMP request from remote system.

How to Configure SNMP Service (Add “public” community string)

  1. Click on Start button, then go to Control Panel.
  2. In Windows Vista, click on System and Maintenance link.
  3. Open Adminstrative Tools.
  4. Run Services applet.
  5. Locate and right click on SNMP Service, then select Properties.
  6. In SNMP Service Properties window, click on Traps tab.
  7. In the “Community name” text box, enter public or any other case-sensitive SNMP community name to which this computer will send trap messages.
  8. Click on Add to list button.


    How to Configure Security for SNMP Service for a Community

  9. Continue from above steps, click on Security tab. If you already close SNMP Service Properties window, re-open it.
  10. Under “Accepted community names” section, click Add button.
  11. Select the appropriate permission level for the community string in the “Community Rights” drop down list to specify how the host processes SNMP requests from the selected community. Normally READ ONLY is recommended.
  12. In the “Community Name” box, type public or any case-sensitive community name that you want.
  13. Click on Add button.
  14. In order for the SNMP service to accept and receive SNMP request packets from any host on the network, including external remote host regardless of identity, click Accept SNMP packets from any host.

    To limit the acceptance of SNMP packets, click Accept SNMP packets from these hosts, and then click Add, and then type the appropriate host name, IP or IPX address in the Host name, IP or IPX address box. You can restrict the access to local host or limited servers only by using this setting. Finish off by clicking Add button again.


  15. Click OK when done. Note that you may need to reboot for the settings to take effect.

Wednesday, September 1, 2010

iftop

iftop show bandwidth usage like top show cpu and memory usage.

First install required software.

yum install libpcap libpcap-devel ncurses ncurses-devel

Now install iftop. Make sure you download latest version from visiting the site http://www.ex-parrot.com/pdw/iftop/

cd /usr/local/src
wget http://www.ex-parrot.com/pdw/iftop/download/iftop-0.17.tar.gz
tar -zxvf iftop-0.17.tar.gz
cd iftop-0.17
./configure
make && make install

By default iftop monitor eth0. To monitor traffic on eth1, run

iftop -i eth1

Install VNstat on nagios

cd /usr/local/src
wget http://humdi.net/vnstat/vnstat-1.10.tar.gz
tar -zxvf vnstat-1.10.tar.gz
cd vnstat-*
make
make install


Create Database

To monitor eth1

/usr/bin/vnstat -u -i eth1

For eth0

/usr/bin/vnstat -u -i eth0

Set init Script


cp examples/init.d/redhat/vnstat /etc/init.d
chkconfig --add vnstat
chkconfig vnstat on
service vnstat start

After installation, it take some time to generate bandwidth usage stats. So you need to wait few hours before you can check the stats. During the time, vnstat cronjob runs and collect data from your server to generate the report.

To see the bandwidth usage stat

vnstat
vnstat -d
vnstat -m
Here is an sample vnstat report
[root@server18 vnstat-1.5]# vnstat
Database updated: Thu Jan 10 10:52:36 2008

eth1

received: 5.24 MB (3.3%)
transmitted: 147.44 MB (96.7%)
total: 152.68 MB

rx | tx | total
-----------------------+------------+-----------
today 5.24 MB | 147.44 MB | 152.68 MB
-----------------------+------------+-----------
estimated 11 MB | 324 MB | 335 MB
[root@server18 vnstat-1.5]#