-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
[WIP] Bootstrap PropertyAccess component #2136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
Property Access | ||
=============== | ||
|
||
.. toctree:: | ||
:maxdepth: 2 | ||
|
||
introduction |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,264 @@ | ||
.. index:: | ||
single: PropertyAccess | ||
single: Components; PropertyAccess | ||
|
||
The PropertyAccess Component | ||
============================ | ||
|
||
PropertyAccess component provides function to read and write from/to an | ||
object or array using a simple string notation. | ||
|
||
.. versionadded:: 2.2 | ||
The PropertyAccess Component is new to Symfony 2.2. Previously, the | ||
``PropertyPath`` class was located in the ``Form`` component. | ||
|
||
Installation | ||
------------ | ||
|
||
You can install the component in two different ways: | ||
|
||
* Use the official Git repository (https://github.com/symfony/PropertyAccess); | ||
* :doc:`Install it via Composer</components/using_components>` * (``symfony/property-access`` on `Packagist`_). | ||
|
||
Usage | ||
----- | ||
|
||
The entry point of this component is the | ||
:method:`Symfony\\Component\\PropertyAccess\\PropertyAccess::getPropertyAccessor` | ||
factory. This factory will create a new instance of the | ||
:class:`Symfony\\Component\\PropertyAccess\PropertyAccessor` class with the | ||
default configuration:: | ||
|
||
use Symfony\Component\PropertyAccess\PropertyAccess; | ||
|
||
$accessor = PropertyAccess:getPropertyAccessor(); | ||
|
||
Reading from arrays | ||
------------------- | ||
|
||
You can read an array with the | ||
:method:`Symfony\\Component\\PropertyAccess\PropertyAccessor::getValue` | ||
method. This is done using the index notation that is used in PHP:: | ||
|
||
// ... | ||
$person = array( | ||
'first_name' => 'Wouter', | ||
); | ||
|
||
echo $accessor->getValue($persons, '[first_name]'); // 'Wouter' | ||
echo $accessor->getValue($person, '[age]'); // null | ||
|
||
As you can see, the method will return ``null`` if the index does not exists. | ||
|
||
You can also use multi dimensional arrays:: | ||
|
||
// ... | ||
$persons = array( | ||
array( | ||
'first_name' => 'Wouter', | ||
), | ||
array( | ||
'first_name' => 'Ryan', | ||
) | ||
); | ||
|
||
echo $accessor->getValue($persons, '[0][first_name]'); // 'Wouter' | ||
echo $accessor->getValue($persons, '[1][first_name]'); // 'Ryan' | ||
|
||
Reading from objects | ||
-------------------- | ||
|
||
The ``getValue`` method is a very robust method. You can see all features if | ||
you are working with objects. | ||
|
||
Using properties | ||
~~~~~~~~~~~~~~~~ | ||
|
||
We can read properties without the index notation, instead we use the dot | ||
notation:: | ||
|
||
// ... | ||
$person = new Person(); | ||
$person->firstName = 'Wouter'; | ||
|
||
echo $accessor->getValue($person, 'first_name'); // 'Wouter' | ||
|
||
$child = new Person(); | ||
$child->firstName = 'Bar'; | ||
$person->children = array($child); | ||
|
||
echo $accessor->getValue($person, 'children[0].first_name'); // 'Bar' | ||
|
||
.. caution:: | ||
|
||
This option is the last option used by the ``PropertyAccessor``. It tries | ||
to find the other options before using the property. If you have a public | ||
property that have a getter to, it will use the getter. | ||
|
||
Using getters | ||
~~~~~~~~~~~~~ | ||
|
||
The ``getValue`` method also supports reading using getters. The method will | ||
be created using common naming conventions for getters. It camelizes the | ||
property name (``first_name`` becomes ``FirstName``) and prefixes it with | ||
``get``. So the actual method becomes ``getFirstName``:: | ||
|
||
// ... | ||
class Person | ||
{ | ||
private $firstName = 'Wouter'; | ||
|
||
public function getFirstName() | ||
{ | ||
return $this->firstName; | ||
} | ||
} | ||
|
||
$person = new Person(); | ||
|
||
echo $accessor->getValue($person, 'first_name'); // 'Wouter' | ||
|
||
Using hassers/issers | ||
~~~~~~~~~~~~~~~~~~~~ | ||
|
||
And it doesn't even stop there. If there is no getter found, the accessor will | ||
look for a isser or hasser. This method is created using the same way as | ||
getters, this means that you can do something like this:: | ||
|
||
// ... | ||
class Person | ||
{ | ||
private $author = true; | ||
private $children = array(); | ||
|
||
public function isAuthor() | ||
{ | ||
return $this->author; | ||
} | ||
|
||
public function hasChildren() | ||
{ | ||
return 0 !== count($this->children); | ||
} | ||
} | ||
|
||
$person = new Person(); | ||
|
||
if ($accessor->getValue($person, 'author')) { | ||
echo 'He is an author'; | ||
} | ||
if ($accessor->getValue($person, 'children')) { | ||
echo 'He has children'; | ||
} | ||
|
||
This will produce: ``He is an author`` | ||
|
||
Magic Methods | ||
~~~~~~~~~~~~~ | ||
|
||
At last, the ``getValue`` can use the magic ``__get`` too:: | ||
|
||
// ... | ||
class Person | ||
{ | ||
private $children = array( | ||
'wouter' => array(...), | ||
); | ||
|
||
public function __get($id) | ||
{ | ||
return $this->children[$id]; | ||
} | ||
} | ||
|
||
$person = new Person(); | ||
|
||
echo $accessor->getValue($person, 'Wouter'); // array(...) | ||
|
||
Writing to arrays | ||
----------------- | ||
|
||
The ``PropertyAccessor`` class can do more than just reading an array, it can | ||
also write to an array. This can be achieved using the | ||
:method:`Symfony\\Component\\PropertyAccess\\PropertyAccessor::setValue` | ||
method:: | ||
|
||
// ... | ||
$person = array(); | ||
|
||
$accessor->setValue($person, '[first_name]', 'Wouter'); | ||
|
||
echo $accessor->getValue($person, '[first_name]'); // 'Wouter' | ||
// or | ||
// echo $person['first_name']; // 'Wouter' | ||
|
||
Writing to objects | ||
------------------ | ||
|
||
The ``setValue`` method has the same features as the ``getValue`` method. You | ||
can use setters, the magic ``__set`` or properties to set values:: | ||
|
||
// ... | ||
class Person | ||
{ | ||
public $firstName; | ||
private $lastName; | ||
private $children = array(); | ||
|
||
public function setLastName($name) | ||
{ | ||
$this->lastName = $name; | ||
} | ||
|
||
public function __set($property, $value) | ||
{ | ||
$this->$property = $value; | ||
} | ||
|
||
// ... | ||
} | ||
|
||
$person = new Person(); | ||
|
||
$accessor->setValue($person, 'firstName', 'Wouter'); | ||
$accessor->setValue($person, 'lastName', 'de Jong'); | ||
$accessor->setValue($person, 'children', array(new Person())); | ||
|
||
echo $person->firstName; // 'Wouter' | ||
echo $person->getLastName(); // 'de Jong' | ||
echo $person->children; // array(Person()); | ||
|
||
Mixing objects and arrays | ||
------------------------- | ||
|
||
You can also mix objects and arrays:: | ||
|
||
// ... | ||
class Person | ||
{ | ||
public $firstName; | ||
private $children = array(); | ||
|
||
public function setChildren($children) | ||
{ | ||
return $this->children; | ||
} | ||
|
||
public function getChildren() | ||
{ | ||
return $this->children; | ||
} | ||
} | ||
|
||
$person = new Person(); | ||
|
||
$accessor->setValue($person, 'children[0]', new Person); | ||
// equal to $person->getChildren()[0] = new Person() | ||
|
||
$accessor->setValue($person, 'children[0].firstName', 'Wouter'); | ||
// equal to $person->getChildren()[0]->firstName = 'Wouter' | ||
|
||
echo 'Hello '.$accessor->getValue($person, 'children[0].firstName'); // 'Wouter' | ||
// equal to $person->getChildren()[0]->firstName | ||
|
||
.. _Packagist: https://packagist.org/packages/symfony/property-access |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be
firstName
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, it will work as the getter would be the same, but it is indeed confusing