Skip to content

Instantly share code, notes, and snippets.

@cahnory
Created October 26, 2012 11:25
Show Gist options
  • Save cahnory/3958275 to your computer and use it in GitHub Desktop.
Save cahnory/3958275 to your computer and use it in GitHub Desktop.
Consistent PHP string object
<?php
class String implements Countable
{
const emptyString = NULL;
const defaultEncoding = 'UTF-8';
const pregFlag = 'u';
/**
* The String content
*
* @var string
* @access protected
*/
protected $string;
/**
* The String encoding
*
* Potential values are
*
* @var string
* @access protected
*/
protected $encoding;
/**
* Return a new String
*
* @param string $string the string content
* @param string $encoding the string encoding
*
* @return String
*
* @access public
*/
public function __construct($string = self::emptyString, $encoding = self::defaultEncoding) {
$this->encoding = $encoding;
$this->string = self::sconvert($string, $this->encoding);
}
/**
* Return the string content
*
* @return string
*
* @access public
*/
public function __toString() {
return $this->string;
}
/**
* Return a String instance
*
* @param string $string the new string
*
* @return String
*
* @access protected
*/
protected function shift($string) {
$string = new String($string, $this->encoding);
return $string;
}
public function output() {
echo $this->string;
return $this;
}
/**
* Convert a string to a new encoding
*
* If the string encoding is the same as the
* new one, the string isn't converted.
*
* @param string $string the string to convert
* @param string $encoding the new encoding
*
* @return string
* @throws Exception The encoding is not supported
*
* @access protected
* @static
*/
protected static function sconvert($string, $encoding) {
if (!in_array($encoding, mb_list_encodings())) {
throw new \Exception('The \'' . $encoding . '\' encoding is not supported');
}
if ($encoding != $detected = mb_detect_encoding($string, mb_detect_order(), true)) {
if($detected) {
$string = mb_convert_encoding($string, $encoding, $detected);
} else {
$string = mb_convert_encoding($string, $encoding);
}
}
return $string;
}
/**
* Return a String clone with a different encoding
*
* @param string $encoding the new encoding
*
* @return String
*
* @access public
* @see String::sconvert(), String::shift()
*/
public function convert($encoding = self::defaultEncoding) {
return $this->shift(self::sconvert($encoding));
}
/**
* Return a new String
*
* @param string $string the string content
* @param string $encoding the string encoding
*
* @return String
*
* @access public
* @static
* @see String::__construct()
*/
public static function get($string = self::emptyString, $encoding = self::defaultEncoding) {
return new String($string, $encoding, false);
}
/**
* Return a String clone with a different content
*
* @param string $string the new string content
*
* @return String
*
* @access public
* @see String::shift()
*/
public function set($string) {
return $this->shift(self::sconvert($string, $this->encoding));
}
// !Subchains
public function replace($needle, $replace, $limit = NULL) {
if ($limit != NULL) {
return $this->shift(preg_replace('#' . preg_quote($needle, '#') . '#sui', $replace, $this->string, $limit));
} else {
return $this->shift(str_replace($needle, $replace, $this->string));
}
}
public function substring($start, $length = NULL) {
if ($length === NULL) {
$length = $this->length() - $start;
}
return $this->shift(mb_substr($this->string, $start, $length, $this->encoding));
}
public function find($needle, $from = 0, $casse = true) {
if ($casse) {
return mb_strpos($this->string, $needle, $from, $this->encoding);
} else {
return mb_stripos($this->string, $needle, $from, $this->encoding);
}
}
public function findLast($needle, $from = 0, $casse = true) {
if ($casse) {
return mb_strrpos($this->string, $needle, $from, $this->encoding);
} else {
return mb_strripos($this->string, $needle, $from, $this->encoding);
}
}
public function findAll($needle, $from = 0, $casse = true) {
$found = array();
if ($casse) {
$i = 0;
while(false !== $from = mb_strpos($this->string, $needle, $from, $this->encoding)) {
$found[] = $from++;
}
} else {
while(false !== $from = mb_stripos($this->string, $needle, $from, $this->encoding)) {
$found[] = $from++;
}
}
return $found;
}
// !Regex
public function pregReplace($pattern, $replace, $limit = -1, &$count = NULL) {
if(is_callable($replace)) {
return $this->shift(preg_replace($pattern.self::pregFlag, $replace, $this->string, $limit));
} else {
return $this->shift(preg_replace_callback($pattern.self::pregFlag, $replace, $this->string, $limit));
}
}
public function pregMatch($pattern, array &$matches = array(), $flags = 0, $offset = 0) {
return preg_match($pattern.self::pregFlag, $this->string, $matches, $flags, $offset);
}
public function pregSplit($pattern, $limit = -1, $flags = 0) {
$chunks = preg_split($pattern.self::pregFlag, $this->string, $limit, $flags);
foreach($chunks as &$chunk) {
$chunk = new String($chunk, $this->encoding);
}
return $chunks;
}
// !Casse
public function lower() {
return $this->shift(mb_strtolower($this->string, $this->encoding));
}
public function upper() {
return $this->shift(mb_strtoupper($this->string, $this->encoding));
}
// !Length
public function count($needle = NULL, $casse = true) {
if ($needle) {
if ($casse) {
return mb_substr_count($this->string, $needle, $this->encoding);
} else {
return sizeof($this->findAll($needle, 0, false));
}
} else {
return $this->length();
}
}
public function length() {
return mb_strlen($this->string, $this->encoding);
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment