SilverStripe PHP5

Preview:

Citation preview

PHP5.4 And SilverStripeOr me geeking off about the latest thing I managed

to compile

Who am I?Simon Welsh - @simon_w

Developer for RentBox

Studying at VUW

http://simon.geek.nz/

AgendaTraits

JSON

Other things

Other thingsBinary number format 0b00101000 0b00000010

Callable type hint function doStuffWithCallback($input, callback $callback) { ... }

Short array syntax [4, 5, ‘index’ => ‘value’]

Improved parse error messages Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM) in - on line 2

<?=

Shouldn’t use with SilverStripe, but now always enabled (even without short tags)

Array dereferencing

$secondItem = DataObject::get(‘SiteTree’)[2];

Removed functionality

Safe mode

Magic quotes

Register globals

break/continue $var;

Other things

JSONConvert::raw2json() just calls json_encode()

Current output isn’t very useful:DataObject: {"destroyed":false,"class":"Member"}DataObjectSet: {"class":"DataObjectSet"}

Could use JSONDataFormatterInstance methods do the convertingNon-recursiveCan’t add information not in a field/relationCode assumes it’s called as part of the API

JSONThe JsonSerializable interface and jsonSerialize() method tie into json_encode()

A class implementing JsonSerializable returns what gets serialised in the jsonSerialize() method.

Allows for a completely customisable serialisation process.

JSONAs it is accessed through json_encode(), it allows for recursion.

Convert::raw2json() uses it automatically in 5.4, and it can even be emulated in ≤5.3.

You can define everything that goes into it, wether that’s fields, relations or some other calculated value.

JSONclass DataObject extends ViewableData implements DataObjectInterface, i18nEntityProvider { ......

class DataObjectSet extends ViewableData implements IteratorAggregate, Countable { ......

JSONclass DataObject extends ViewableData implements DataObjectInterface, i18nEntityProvider, JsonSerializable { public function jsonSerialize() { return $this->record; } ......

class DataObjectSet extends ViewableData implements IteratorAggregate, Countable, JsonSerializable { public function jsonSerialize() { return $this->items; } ......

JSONBefore:{"destroyed":false,"class":"Member"}{"class":"DataObjectSet"}After:{"ClassName":"Member","Created":"2011-08-20 18:15:59","LastEdited":"2011-08-20 18:35:25","FirstName":"Default Admin","NumVisit":"1","LastVisited":"2011-08-20 22:09:51.437521","Bounced":"0","Locale":"en_NZ","FailedLoginCount":"0","ID":1,"RecordClassName":"Member"}[{"ClassName":"Member","Created":"2011-08-20 18:15:59","LastEdited":"2011-08-20 18:35:25","FirstName":"Default Admin","NumVisit":"1","LastVisited":"2011-08-20 22:09:51.437521","Bounced":"0","Locale":"en_NZ","FailedLoginCount":"0","ID":1,"RecordClassName":"Member"}]

JSONpublic function jsonSerialize() { $extended = $this->extendedCan('jsonSerialize', null); if($extended !== null) { return $extended; } return $this->record;}[ { "Date": "11 Feb 2011", "Issue": "Grounds", "Notes": "Grounds are very mature and the whole section needs to be ...", "Fixed": true, "FixedDate": "19 Apr 2011", "How": null, "Cost": "$0.00", "Type": "Outdoor Maintenance", "Urgent": false, "Contractor": null, "ID": 9, "Actions": [ { "ID": 7, "Title": "Grounds and stove", "Finished": false, } ] }, { ...

TraitsHorizontal code reuse

“In computer programming, a trait is a collection of methods, used as a "simple conceptual model for structuring object oriented programs".”

Similar to DataObjectDecorators/Extensions

TraitsSimilar deceleration to classes and interfaces:trait MyTrait { ... }

Can only define methods, so no properties

Methods can be abstract and static

Method visibility need not be respected

Traits can be composed from other traits

TraitsTraits inject their methods into the class that is including the trait

Injected methods can be renamed, have their visibility changed and cherry-picked in the case of conflicts

Default precedence for methods is current class, traits, then inherited methods.

TraitsTraits are mainly for horizontal code reuse. That is having the same code in different classes in different parts of the inheritance structure.

Allows for less code duplication without some nasty inheritance structure.

Traitsspl_autoload_register(function($className) { if(strtolower(substr($className, -5)) == 'trait') { if(file_exists(__DIR__ . "/traits/$className.php")) { include __DIR__ . "/traits/$className.php"; } }});

Traitstrait AddressData { public function setAddressData($data) { $data = json_decode($data, true); ... $this->Street = sprintf('%s%s %s', $data['number'], empty($data['alpha']) ? '' : $data['alpha'], $data['street']); ... if($suburb && $suburb->exists()) { $this->SuburbID = $suburb->ID; } else { $suburb = new Suburb; $suburb->Name = $data['suburb']; $suburb->DistrictID = $this->DistrictID; $this->SuburbID = $suburb->write(); } $this->setField('AddressData', json_encode($data)); }}

Traitsclass Property extends DataObject { use AddressData; public static $db = [ ... ‘AddressData’ => ‘Text’, ...];}

class CustomMember extends DataObjectDecorator { use AddressData; public function extraStatics() { return [‘db’ => [ ... ‘AddressData’ => ‘Text’, ...]]; }}