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:
- Reverse the letters
- Uppercase each word
- Replace all white spaces with “_”
- 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:
- Cleaner to read
- Easier to use and maintain
- Looks cool 🙂
- 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?
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
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
here is the best tutorial you can start with Zend Framework Quick Start, Source code.
Are you using Zend_Application and bootstrap class or not? Can you show me the code in your index.php?
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
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