PHP string functions to Class

Would it be better if all PHP string functions are methods of a String class?
Would that make working with strings an easy job? and make the code easier to read and maintain?

Here is my experiment on wrapping some of the built in functions into a class.


Let say we want to modify a string:

  1. Reverse the letters
  2. Uppercase each word
  3. Replace all white spaces with “_”
  4. Convert the string into array

Using PHP built-in functions:

Example 1

$string = 'hello mohammed';
$string = explode('_', str_replace(' ','_', ucfirst(strrev($string))));

Example 2

$string = 'hello mohammed';
$string = strrev($string);
$string = ucfirst($string);
$string = str_replace(' ','_', $string);
$string = explode('_', $string);

Object Oriented Approach:

The String class:

/**
 * @author     Mohammed Alsharaf
 * @category   My
 * @package    My_String
 * @copyright  Copyright (c) 2008-2009 Mohammed Alsharaf.
 * @license    http://framework.zend.com/license/new-bsd
 */
class My_String {
    protected $_string = '';
    protected $_info = array();
    
    public function __construct($string=null) {
        $string = empty($string)? '' : $string;
        $this->_string = $string;
    }
    
    public function reverse() {
    	$this->_string = strrev($this->_string);
    	return $this;
    }
    
    public function extract($start, $length) {
    	$this->_string = substr($this->_string, $start, $length);
    	return $this;
    }
    
    public function wordwrap($width, $break = "\n", $cut = false) {
    	$this->_string = wordwrap($this->_string, $width, $break, $cut);
    	return $this;
    }
    
    public function ucfirst() {
    	$this->_string = ucfirst($this->_string);
    	return $this;
    }
    
    public function toLowerCase() {
    	$this->_string = strtolower($this->_string);
    	return $this;
    }
    
    public function replace($search, $replace, $caseInsensitive = false) {
    	$result = '';
    	if($caseInsensitive === false) {
    		$this->_string = str_replace($search, $replace, $this->_string, $result);
    	} else {
    		$this->_string = str_ireplace($search, $replace, $this->_string, $result);
    	}
    	$this->_setInfo(__METHOD__, $result);
    	return $this;
    }
    
    public function toArray($delimiter = '_', $limit=null) { 
        if(null === $limit) {
           $string = explode($delimiter, $this->_string);
        } else {
           $string = explode($delimiter, $this->_string, $limit);
        }
        if(false === $string) {
        	$string = array();
        }
    	return new My_Array($string);
    }
 
 	public function getInfo() {
 		return $this->_info;
 	}
 	
 	protected function _setInfo($method, $data) {
 		$this->_info[$method] = $data;
 		return $this;
 	}
 	
    public function __toString() {
    	return $this->_string;
    }
}

Usage:

$string = new My_String('hello mohammed');
$newString = $string->reverse()
		   ->ucfirst()
		   ->replace(' ', '_')
		   ->toArray('_');

In my opinon the object oriented approach is much better than using the built-in functions for the reasons:

  1. Cleaner to read
  2. Easier to use and maintain
  3. Looks cool 🙂
  4. Its Object Oriented Programming

Ok, what about the preformace?

Bechmark the above examples using Pear Bechmark, the result is as follow:

Using OOP:

  time index ex time %
Start 1255570008.74220000 0.00%
Mark1 1255570008.74292300 0.000723 95.01%
Stop 1255570008.74296100 0.000038 4.99%
total 0.000761 100.00%

PHP built-in functions (Example 1):

  time index ex time %
Start 1255569909.34220000 0.00%
Mark1 1255569909.34224100 0.000041 54.67%
Stop 1255569909.34227500 0.000034 45.33%
total 0.000075 100.00%

PHP built-in functions (Example 2):

  time index ex time %
Start 1255569968.43419900 0.00%
Mark1 1255569968.43424400 0.000045 56.96%
Stop 1255569968.43427800 0.000034 43.04%
total 0.000079 100.00%

The Benchmark code used:

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
	realpath('C:\Apache Software Foundation\htdocs\test\library'),
	get_include_path(),
)));

require_once 'Benchmark/Timer.php';

$timer = new Benchmark_Timer();
$timer->start();

/*** here examples code ***/

$timer->setMarker('Mark1');

$timer->stop();
$timer->display();

What is your thoughts on this?

Posted in PHP and tagged , .
Loading Facebook Comments ...

Leave a Reply

Your email address will not be published. Required fields are marked *

6 Comments

  1. I’ve got everything up and running. Thanks. Is it possible to use this string functions on the fly?

    So only add enter the function after the variable and not create a new object My_String();

    I’ve tried to make this work by adding

    class My_String extends Zend_Application {

    but this doesn’t work. Do you have suggestions?

    Cheers!

    • I am not sure what you are trying to achieve. Could you explain more?

      Also, you should not extend Zend_Application. My_String is a class to make working with string easy and simple.

      $string = new My_String('My string'); // this same as if you do this
      $string = 'My string';

      So every time you want to create a string you need to create a new instance of My_String.

      But if you want one instance of My_String in your application, then you have to find a way to do this, either by using singleton or action helper to reuse in your controller, or other ways….

      But let say you have an action helper for My_String, called “My_Controller_Action_Helper_String”. In your action you can do this

      $string = $this->_helper->string('my new string');

      Hope this helps

  2. I’m loving ZF too so far, it is much joy and happiness but the but the learning curve is not as steep as a expected to be. A lot of tutorials are not for ZF 10.2.*….

    I’m getting the error ‘Class ‘Zend_Loader_Autoloader’ not found in …’ when I add to my index.php:

    $autoloader = Zend_Loader_Autoloader::getInstance();
    $autoloader->registerNamespace(array(My_’));

    Could you say me how to avoid this?

    Thanks!

    Crispijn

  3. Hi

    Thanks for the interest in the code 🙂

    It’s not limited to Zend Framework, I just love ZF 🙂

    How you could use it in ZF:
    1.
    add My_ to autoloader namespaces. You can do this from configuration.ini autoloaderNamespaces[] = “My_” or in your bootstrap
    $autoloader = Zend_Loader_Autoloader::getInstance();
    $autoloader->registerNamespace(array(‘My_’));

    2. Under library next to Zend folder create folder named My and inside it create PHP file name String.php

    You are done.

    The above steps just to let Zend autoloader knows about the class and then auto load it when you call the class.

    Hope this helps

  4. I’m new to Zend but I like this approach. It’s easy to read. What do I need to do to get this up and running? I’m really a newbie with Zend so can you give me a detailed manual?

    Thanks in advance!

    Crispijn