From c230885a13f7c6f2e8fdd029ca73bf67baa7e48e Mon Sep 17 00:00:00 2001 From: "Daniel St. Jules" Date: Sun, 15 Dec 2013 01:08:23 -0500 Subject: [PATCH] Require objects to have a __toString method, update readme --- README.md | 29 +++++++++++++++---------- src/Stringy/StaticStringy.php | 8 ++----- src/Stringy/Stringy.php | 34 ++++++++++++++++------------- tests/Stringy/StringyTest.php | 41 +++++++++++++++++++++-------------- 4 files changed, 64 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 956f4c6..47e9b5c 100644 --- a/README.md +++ b/README.md @@ -67,13 +67,15 @@ A PHP library with a variety of string manipulation functions with multibyte sup ## Requiring/Loading -If you're using Composer to manage dependencies, you can include the following in your composer.json file: +If you're using Composer to manage dependencies, you can include the following +in your composer.json file: "require": { "danielstjules/stringy": "dev-master" } -Then, after running `composer update` or `php composer.phar update`, you can load the class using Composer's autoloading: +Then, after running `composer update` or `php composer.phar update`, you can +load the class using Composer's autoloading: ```php require 'vendor/autoload.php'; @@ -106,9 +108,9 @@ use Stringy\Stringy as S; echo S::create('Fòô Bàř', 'UTF-8')->collapseWhitespace()->swapCase(); // 'fÒÔ bÀŘ' ``` -`Stringy\Stringy` contains a __toString() method, which returns the current -string when the object is used in a string context. Its $str property is also -public, and can be accessed directly if required, ie: `S::create('foo')->str // 'foo'` +`Stringy\Stringy` has a __toString() method, which returns the current string +when the object is used in a string context, ie: +`(string) S::create('foo') // 'foo'` Using the static wrapper, an alternative is the following: @@ -120,8 +122,10 @@ echo S::swapCase($string, 'UTF-8'); // 'fÒÔ bÀŘ' ## Methods -In the list below, any static method other than S::create refers to a -method in `Stringy\StaticStringy`. For all others, they're found in `Stringy\Stringy`. Furthermore, all methods that return a Stringy object or string do not modify the original. +In the list below, any static method other than S::create refers to a method in +`Stringy\StaticStringy`. For all others, they're found in `Stringy\Stringy`. +Furthermore, all methods that return a Stringy object or string do not modify +the original. *Note: If `$encoding` is not given, it defaults to `mb_internal_encoding()`.* @@ -200,11 +204,13 @@ S::count('Ο συγγραφέας είπε', 'α', 'UTF-8'); // 2 #### create -S::create(string $str, [, $encoding ]) +S::create(mixed $str, [, $encoding ]) Creates a Stringy object and assigns both str and encoding properties -the supplied values. If $encoding is not specified, it defaults to -mb_internal_encoding(). It then returns the initialized object. +the supplied values. $str is cast to a string prior to assignment, and if +$encoding is not specified, it defaults to mb_internal_encoding(). It +then returns the initialized object. Throws an InvalidArgumentException +if the first argument is an array or object without a __toString method. ```php $stringy = S::create('fòô bàř', 'UTF-8'); // 'fòô bàř' @@ -639,7 +645,8 @@ $stringy->shuffle() S::shuffle(string $str [, string $encoding ]) -A multibyte str_shuffle() function. It returns a string with its characters in random order. +A multibyte str_shuffle() function. It returns a string with its characters in +random order. ```php S::create('fòô bàř', 'UTF-8')->shuffle(); diff --git a/src/Stringy/StaticStringy.php b/src/Stringy/StaticStringy.php index 10691d0..c6cd773 100644 --- a/src/Stringy/StaticStringy.php +++ b/src/Stringy/StaticStringy.php @@ -763,11 +763,7 @@ class StaticStringy public static function regexReplace($str, $pattern, $replacement, $options = 'msr', $encoding = null) { - return (string) Stringy::create($str, $encoding) - ->regexReplace( - $pattern, - $replacement, - $options, - $encoding); + return (string) Stringy::create($str, $encoding)->regexReplace($pattern, + $replacement, $options, $encoding); } } diff --git a/src/Stringy/Stringy.php b/src/Stringy/Stringy.php index c7096f2..e296dbd 100644 --- a/src/Stringy/Stringy.php +++ b/src/Stringy/Stringy.php @@ -4,46 +4,50 @@ namespace Stringy; class Stringy { - /** - * @var string - */ private $str; public $encoding; /** * Initializes a Stringy object and assigns both str and encoding properties - * the supplied values. If $encoding is not specified, it defaults to - * mb_internal_encoding(). + * the supplied values. $str is cast to a string prior to assignment, and if + * $encoding is not specified, it defaults to mb_internal_encoding(). Throws + * an InvalidArgumentException if the first argument is an array or object + * without a __toString method. * - * @param string $str String to modify - * @param string $encoding The character encoding - * - * @throws \InvalidArgumentException if array or resource passed to constructor instead of string + * @param mixed $str Value to modify, after being cast to string + * @param string $encoding The character encoding + * @throws \InvalidArgumentException if an array or object without a + * __toString method is passed as the first argument */ public function __construct($str, $encoding = null) { if (is_array($str)) { throw new \InvalidArgumentException( - 'Expecting string, array given' + 'Passed value cannot be an array' ); - } else if (is_resource($str)) { + } else if (is_object($str) && !method_exists($str, '__toString')) { throw new \InvalidArgumentException( - 'Expecting string, resource given' + 'Passed object must have a __toString method' ); } + $this->str = (string) $str; $this->encoding = $encoding ?: mb_internal_encoding(); } /** * Creates a Stringy object and assigns both str and encoding properties - * the supplied values. If $encoding is not specified, it defaults to - * mb_internal_encoding(). It then returns the initialized object. + * the supplied values. $str is cast to a string prior to assignment, and if + * $encoding is not specified, it defaults to mb_internal_encoding(). It + * then returns the initialized object. Throws an InvalidArgumentException + * if the first argument is an array or object without a __toString method. * - * @param string $str String to modify + * @param mixed $str Value to modify, after being cast to string * @param string $encoding The character encoding * @return Stringy A Stringy object + * @throws \InvalidArgumentException if an array or object without a + * __toString method is passed as the first argument */ public static function create($str, $encoding = null) { diff --git a/tests/Stringy/StringyTest.php b/tests/Stringy/StringyTest.php index 5db2ff8..aaa6910 100644 --- a/tests/Stringy/StringyTest.php +++ b/tests/Stringy/StringyTest.php @@ -15,35 +15,44 @@ class StringyTestCase extends CommonTest $this->assertEquals('UTF-8', $stringy->encoding); } - public function testToString() - { - // Correct work for primitives - $this->assertSame('', (string) new S(null)); - $this->assertSame('', (string) new S(false)); - $this->assertSame('1', (string) new S(true)); - $this->assertSame('-9', (string) new S(-9)); - $this->assertSame('1.18', (string) new S(1.18)); - $this->assertSame(' string ', (string) new S(' string ')); - } - /** * @expectedException InvalidArgumentException */ - public function testToStringArray() + public function testConstructWithArray() { (string) new S(array()); - $this->fail('Expecting exception on receiving array as constructor argument'); + $this->fail('Expecting exception when the constructor is passed an array'); } /** * @expectedException InvalidArgumentException */ - public function testToStringResource() + public function testMissingToString() { - (string) new S(fopen('php://stdout', 'w')); - $this->fail('Expecting exception on receiving resource as constructor argument'); + (string) new S(new stdClass()); + $this->fail('Expecting exception when the constructor is passed an ' . + 'object without a __toString method'); } + /** + * @dataProvider toStringProvider() + */ + public function testToString($expected, $str) + { + $this->assertEquals($expected, (string) new S($str)); + } + + public function toStringProvider() + { + return array( + array('', null), + array('', false), + array('1', true), + array('-9', -9), + array('1.18', 1.18), + array(' string ', ' string ') + ); + } public function testCreate() {