mirror of
https://github.com/danielstjules/Stringy.git
synced 2025-08-12 08:14:06 +02:00
Update ArrayAccess interface implementation, add details to readme
This commit is contained in:
29
README.md
29
README.md
@@ -126,32 +126,39 @@ echo S::swapCase($string, 'UTF-8'); // 'fÒÔ bÀŘ'
|
|||||||
|
|
||||||
## Implemented Interfaces
|
## Implemented Interfaces
|
||||||
|
|
||||||
`Stringy\Stringy` implements the `IteratorAggregate` interface. This allows you
|
`Stringy\Stringy` implements the `IteratorAggregate` interface, meaning that
|
||||||
to use `foreach` with an instance of the class:
|
`foreach` can be used with an instance of the class:
|
||||||
|
|
||||||
``` php
|
``` php
|
||||||
$stringy = S::create('Fòô Bàř', 'UTF-8');
|
$stringy = S::create('Fòô Bàř', 'UTF-8');
|
||||||
|
|
||||||
foreach ($stringy as $char) {
|
foreach ($stringy as $char) {
|
||||||
echo $char;
|
echo $char;
|
||||||
}
|
}
|
||||||
// 'Fòô Bàř'
|
// 'Fòô Bàř'
|
||||||
|
|
||||||
$array = array();
|
|
||||||
foreach ($stringy as $pos => $char) {
|
|
||||||
$array[$pos] = $char;
|
|
||||||
}
|
|
||||||
// array('F', 'ò', 'ô', ' ', 'B', 'à', 'ř')
|
|
||||||
```
|
```
|
||||||
|
|
||||||
It also implements the `Countable` interface, enabling the use of `count()` to
|
It implements the `Countable` interface, enabling the use of `count()` to
|
||||||
retrieve the number of characters in the string, given the encoding:
|
retrieve the number of characters in the string:
|
||||||
|
|
||||||
``` php
|
``` php
|
||||||
$stringy = S::create('Fòô', 'UTF-8');
|
$stringy = S::create('Fòô', 'UTF-8');
|
||||||
count($stringy); // 3
|
count($stringy); // 3
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Furthermore, the `ArrayAccess` interface has been implemented. As a result,
|
||||||
|
`isset()` can be used to check if a character at a specific index exists. And
|
||||||
|
since `Stringy\Stringy` is immutable, any call to `offsetSet` or `offsetUnset`
|
||||||
|
will throw an exception. `offsetGet` has been implemented, however, and accepts
|
||||||
|
both positive and negative indexes. Invalid indexes result in an
|
||||||
|
`OutOfBoundsException`.
|
||||||
|
|
||||||
|
``` php
|
||||||
|
$stringy = S::create('Bàř', 'UTF-8');
|
||||||
|
echo $stringy[2]; // 'ř'
|
||||||
|
echo $stringy[-2]; // 'à'
|
||||||
|
isset($stringy[-4]); // false
|
||||||
|
```
|
||||||
|
|
||||||
## Methods
|
## Methods
|
||||||
|
|
||||||
In the list below, any static method other than S::create refers to a method in
|
In the list below, any static method other than S::create refers to a method in
|
||||||
|
@@ -88,78 +88,69 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not a character exists at the given index. Implements
|
* Returns whether or not a character exists at an index. Offsets may be
|
||||||
|
* negative to count from the last character in the string. Implements
|
||||||
* part of the ArrayAccess interface.
|
* part of the ArrayAccess interface.
|
||||||
*
|
*
|
||||||
* @param mixed $offset The index to check
|
* @param mixed $offset The index to check
|
||||||
* @return boolean Whether or not the index exists
|
* @return boolean Whether or not the index exists
|
||||||
*/
|
*/
|
||||||
public function offsetExists($offset) {
|
public function offsetExists($offset) {
|
||||||
return ($this->length() > (int) $offset);
|
$length = $this->length();
|
||||||
|
$offset = (int) $offset;
|
||||||
|
|
||||||
|
if ($offset >= 0) {
|
||||||
|
return ($length > $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($length >= abs($offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the character at the given index, otherwise null if none exists.
|
* Returns the character at the given index. Offsets may be negative to
|
||||||
* Implements part of the ArrayAccess interface.
|
* count from the last character in the string. Implements part of the
|
||||||
|
* ArrayAccess interface, and throws an OutOfBoundsException if the index
|
||||||
|
* does not exist.
|
||||||
*
|
*
|
||||||
* @param mixed $offset The index from which to retrieve the char
|
* @param mixed $offset The index from which to retrieve the char
|
||||||
* @return mixed The character if it exists, else null
|
* @return mixed The character at the specified index
|
||||||
|
* @throws \OutOfBoundsException If the positive or negative offset does
|
||||||
|
* not exist
|
||||||
*/
|
*/
|
||||||
public function offsetGet($offset) {
|
public function offsetGet($offset) {
|
||||||
$offset = (int) $offset;
|
$offset = (int) $offset;
|
||||||
if ($this->length() <= $offset) {
|
$length = $this->length();
|
||||||
return null;
|
|
||||||
|
if (($offset >= 0 && $length <= $offset) || $length < abs($offset)) {
|
||||||
|
throw new \OutOfBoundsException('No character exists at the index');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->at($offset);
|
return mb_substr($this->str, $offset, 1, $this->encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the character at the given offset. The value to set is truncated
|
* Implements part of the ArrayAccess interface, but throws an exception
|
||||||
* to a single character. If the offset is null or exceeds the length
|
* when called. This maintains the immutability of Stringy objects.
|
||||||
* of the string, it is appended to the end. Implements part of the
|
|
||||||
* ArrayAccess interface.
|
|
||||||
*
|
*
|
||||||
* @param mixed $offset The index at which to replace the character
|
* @param mixed $offset The index of the character
|
||||||
* @param mixed $value Value to set
|
* @param mixed $value Value to set
|
||||||
|
* @throws \Exception When called
|
||||||
*/
|
*/
|
||||||
public function offsetSet($offset, $value) {
|
public function offsetSet($offset, $value) {
|
||||||
$length = $this->length();
|
// Stringy is immutable, cannot directly set char
|
||||||
if ($offset === null || $length <= (int) $offset) {
|
throw new \Exception('Stringy object is immutable, cannot modify char');
|
||||||
$this->str .= $value;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$offset = (int) $offset;
|
|
||||||
$value = mb_substr($value, 0, 1, $this->encoding);
|
|
||||||
$start = mb_substr($this->str, 0, $offset, $this->encoding);
|
|
||||||
$end = mb_substr($this->str, $offset + 1, $length, $this->encoding);
|
|
||||||
|
|
||||||
$this->str = $start . $value . $end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes character at the given offset. Implements part of the
|
* Implements part of the ArrayAccess interface, but throws an exception
|
||||||
* ArrayAccess interface.
|
* when called. This maintains the immutability of Stringy objects.
|
||||||
*
|
*
|
||||||
* @param mixed $offset The index at which to delete the character
|
* @param mixed $offset The index of the character
|
||||||
|
* @throws \Exception When called
|
||||||
*/
|
*/
|
||||||
public function offsetUnset($offset) {
|
public function offsetUnset($offset) {
|
||||||
$length = $this->length();
|
// Don't allow directly modifying the string
|
||||||
if ($offset === null || $length <= (int) $offset) {
|
throw new \Exception('Stringy object is immutable, cannot unset char');
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$offset = (int) $offset;
|
|
||||||
if ($offset === $length - 1) {
|
|
||||||
$this->str = $this->substr(0, $length - 1)->str;
|
|
||||||
}
|
|
||||||
|
|
||||||
$start = mb_substr($this->str, 0, $offset, $this->encoding);
|
|
||||||
$end = mb_substr($this->str, $offset + 1, $length, $this->encoding);
|
|
||||||
|
|
||||||
$this->str = $start . $end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -95,16 +95,26 @@ class StringyTestCase extends CommonTest
|
|||||||
$this->assertEquals(array('F', 'ò', 'ô', ' ', 'B', 'à', 'ř'), $keyValResult);
|
$this->assertEquals(array('F', 'ò', 'ô', ' ', 'B', 'à', 'ř'), $keyValResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testOffsetExists()
|
/**
|
||||||
|
* @dataProvider offsetExistsProvider()
|
||||||
|
*/
|
||||||
|
public function testOffsetExists($expected, $offset)
|
||||||
{
|
{
|
||||||
$stringy = S::create('fòô', 'UTF-8');
|
$stringy = S::create('fòô', 'UTF-8');
|
||||||
|
$this->assertEquals($expected, $stringy->offsetExists($offset));
|
||||||
|
$this->assertEquals($expected, isset($stringy[$offset]));
|
||||||
|
}
|
||||||
|
|
||||||
$this->assertTrue($stringy->offsetExists(0));
|
public function offsetExistsProvider()
|
||||||
$this->assertTrue($stringy->offsetExists(2));
|
{
|
||||||
$this->assertFalse($stringy->offsetExists(3));
|
return array(
|
||||||
|
array(true, 0),
|
||||||
$this->assertTrue(isset($stringy[2]));
|
array(true, 2),
|
||||||
$this->assertFalse(isset($stringy[3]));
|
array(false, 3),
|
||||||
|
array(true, -1),
|
||||||
|
array(true, -3),
|
||||||
|
array(false, -4)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testOffsetGet()
|
public function testOffsetGet()
|
||||||
@@ -113,61 +123,35 @@ class StringyTestCase extends CommonTest
|
|||||||
|
|
||||||
$this->assertEquals('f', $stringy->offsetGet(0));
|
$this->assertEquals('f', $stringy->offsetGet(0));
|
||||||
$this->assertEquals('ô', $stringy->offsetGet(2));
|
$this->assertEquals('ô', $stringy->offsetGet(2));
|
||||||
$this->assertEquals(null, $stringy->offsetGet(3));
|
|
||||||
|
|
||||||
$this->assertEquals('ô', $stringy[2]);
|
$this->assertEquals('ô', $stringy[2]);
|
||||||
$this->assertEquals(null, $stringy[3]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider offsetSetProvider()
|
* @expectedException \OutOfBoundsException
|
||||||
*/
|
*/
|
||||||
public function testOffsetSet($expected, $offset, $value)
|
public function testOffsetGetOutOfBounds()
|
||||||
{
|
{
|
||||||
$stringy = S::create('fòô', 'UTF-8');
|
$stringy = S::create('fòô', 'UTF-8');
|
||||||
$stringy->offsetSet($offset, $value);
|
$test = $stringy[3];
|
||||||
$this->assertEquals($expected, (string) $stringy);
|
|
||||||
|
|
||||||
$stringy = S::create('fòô', 'UTF-8');
|
|
||||||
$stringy[$offset] = $value;
|
|
||||||
$this->assertEquals($expected, (string) $stringy);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function offsetSetProvider()
|
|
||||||
{
|
|
||||||
return array(
|
|
||||||
array('ôòô', 0, 'ô'),
|
|
||||||
array('fòo', 2, 'o'),
|
|
||||||
array('fòôô', 3, 'ô'),
|
|
||||||
array('fòôô', 8, 'ô'),
|
|
||||||
array('fòôô', null, 'ô'),
|
|
||||||
array('fô', 1, ''),
|
|
||||||
array('fbô', 1, 'bar')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider offsetUnsetProvider()
|
* @expectedException \Exception
|
||||||
*/
|
*/
|
||||||
public function testOffsetUnset($expected, $offset)
|
public function testOffsetSet()
|
||||||
{
|
{
|
||||||
$stringy = S::create('fòô', 'UTF-8');
|
$stringy = S::create('fòô', 'UTF-8');
|
||||||
$stringy->offsetUnset($offset);
|
$stringy[1] = 'invalid';
|
||||||
$this->assertEquals($expected, (string) $stringy);
|
|
||||||
|
|
||||||
$stringy = S::create('fòô', 'UTF-8');
|
|
||||||
unset($stringy[$offset]);
|
|
||||||
$this->assertEquals($expected, (string) $stringy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function offsetUnsetProvider()
|
/**
|
||||||
|
* @expectedException \Exception
|
||||||
|
*/
|
||||||
|
public function testOffsetUnset()
|
||||||
{
|
{
|
||||||
return array(
|
$stringy = S::create('fòô', 'UTF-8');
|
||||||
array('òô', 0),
|
unset($stringy[1]);
|
||||||
array('fô', 1),
|
|
||||||
array('fò', 2),
|
|
||||||
array('fòô', 3)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user