Last active
September 30, 2017 01:22
-
-
Save Antnee/237334e1eb937892ad7a to your computer and use it in GitHub Desktop.
PHP7 Structs
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
<?php | |
/** | |
* Ideas for how I'd like to see structs implemented in PHP7 | |
* | |
* In this example, structs are more like lightweight objects that have no | |
* methods, just properties. They can be "instantiated" and all properties will be | |
* null until defined later, as per classes. It is however not possible to set a | |
* value to a property that was not defined in the struct originally. | |
* | |
* Structs can extend other structs, much like classes can. Properties can also | |
* have default values, just as classes can. All properties are public. It is | |
* possible to override previous default property values in the extending struct, | |
* as is done in classes. | |
* | |
* During instantiation, it is possible to set properties in a similar fashion to | |
* defining array keys and values, ie with named arguments. | |
* | |
* Structs are first class. | |
*/ | |
namespace antnee; | |
struct User { | |
string $name; | |
string $email; | |
bool $active; | |
int $maxLogins; | |
} | |
$user = new User; | |
$user->name = 'Antnee'; | |
$user->email = '[email protected]'; | |
$user->active = true; | |
$user->maxLogins = 'yes'; // Throw a catchable fatal error - incorrect type | |
$user->foo = 'bar'; // Throw a catchable fatal error - unknown property | |
/** | |
* Populating a Struct via a _constructor_ looks like a mix of object and array | |
*/ | |
$user = new User( | |
'name' => 'Antnee', | |
'email' => '[email protected]', | |
'active' => true, | |
'maxLogins' => 3, | |
); | |
/** | |
* Function taking a User struct as an argument | |
*/ | |
function acceptUserStruct(User $struct): User { | |
var_dump($struct); | |
return $struct; | |
} | |
acceptUserStruct($user); | |
/** | |
* Extending a struct | |
*/ | |
struct AdminUser extends User { | |
int $maxLogins = -1; | |
bool $admin = true; | |
} | |
$admin = new AdminUser( | |
'name' => 'Antnee', | |
'email' => '[email protected]', | |
'active' => true | |
); | |
echo json_encode($admin); | |
/* Echoes: | |
{ | |
"name": "Antnee", | |
"email": "[email protected]", | |
"active": true, | |
"maxLogins": -1, | |
"admin": true | |
} | |
*/ | |
/** | |
* Pass in _anonymous_ struct as argument | |
*/ | |
$name = 'Me'; | |
$email = '[email protected]'; | |
$active = true; | |
$maxLogins = 5; | |
echo json_encode( | |
struct { | |
'name' => $name, | |
'email' => $email, | |
'active' => $active, | |
'maxLogins' => $maxLogins, | |
} | |
); | |
/* Echoes: | |
{ | |
"name": "Me", | |
"email": "[email protected]", | |
"active": true, | |
"maxLogins": 5 | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@dshafik and @Rican7 : We've just been looking at the namespacing issue, and we don't feel that it's any worse than the class/interface/trait issue, because:
PHP Fatal error: Cannot redeclare class abc in test.php on line 3
PHP Fatal error: Cannot redeclare class abc in test.php on line 3
PHP Fatal error: Cannot redeclare class abc in test.php on line 3
So you can't have a trait, interface or class in the same namespace with the same name anyway. Not in PHP 5.x anyway. Unsure about PHP 7 (untested), but if it behaves the same then it would be consistent and everyone's happy, yes?
Thanks @gallna for looking into this