|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2008-11-06 14:11 UTC] glideraerobatics at hotmail dot com
Description: ------------ Here is a description of this feature in C#: http://blog.paranoidferret.com/index.php/2007/09/12/csharp-tutorial-the-readonly-keyword/ In a nutshell it allows you to create classes with public variables that are readonly and can only be written to / initialized by the contructor of the class itself. This allows the creation of simple objects without having using accessor methods to protect the internal data that was validated and initialized during construction from corruption. Note: bug http://bugs.php.net/bug.php?id=39467 is about a similar problem but the proposed solution is not quite right. Reproduce code: --------------- class Person { public readonly $name = null; public readonly $age = null; public readonly $weight = null; public function __construct($name, $age, $weight) { { if (!isAgeToWeightRatioSane($age, $weight)) { throw new InvalidArgumentException("Invalid age to weight ratio: $age : $weight"); } // TODO: other sanity checks here. $this->name = $name; $this->age = $age; $this->weight = $weight; } } $person = new Person('Joe', 22, 100); $person->age = 33; // throws a yet to be named exception PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Nov 07 14:00:02 2025 UTC |
I guess the readonly keyword in C# is wrong. It hasn't to disallow variance of the attribute, but the setting from outside the object. Readonly is opposite to constness of a variable. For example, DOMDocument::doctype isn't constant. What you think about, it's a dynamic const attribute, in opposite to static one. So said, a readonly is like a const attribute, but isn't. And it doesn't deserve a scope qualifier, it can only be public. For example : class thing { readonly $status = 'instantiation' ; public function __construct() { // do init stuff $this->status = 'instantiate' ; } public function invalidate() { // do stuf $this->status = 'invalid' ; } } // Usage $o = new thing ; echo $o->status ; // display 'instantiation' $o->status = 'forced' ; // throw an error E_FATAL $o->invalidate() ; // do stuff then set readonly status attributeI just want the "readonly" keyword to protect a property from being written to from the outside. I still want to write to the property from within the class. Here's a simple example of how it could be used: class Parent { readonly public $children = array(); public function addChild($childName) { $this->children[] = ucwords(strtolower($childName)); } } $parent = new Parent; $parent->addChild("billy"); $count = count($parent->children); // You can do this print "Parent has $count children\n"; $name = $parent->children[0]; // You can even do this print "Parent's first child's name is $name\n"; $parent->children[0] = "BILLY"; // But you can't do this $parent->children[] = "BOB"; // Or this $parent->children = NULL; // Or this unset($parent->children); // Or this The above example frees you from having to do this: class Parent { protected $children = array(); public function addChild($childName) { $this->children[] = ucwords(strtolower($childName)); } public function hasChild($index) { return isset($this->children[$index]); } public function getChild($index) { return $this->children[$index]; } public function childCount() { return count($this->children); } } I've had to write MANY classes like this. The has/isset, get, and count functions are virtually all the same. Some people have even resorted to using __get and __set: http://stackoverflow.com/questions/402215/php-readonly-properties The __get and __set magic functions are slow, so much so you're better off making your own getters and setters, which is multiplied by the number of properties you need like this in the class. I would recommend the following definitions: readonly public = read for public, write for protected readonly protected = read for protected, write for private I think this should satisfy most cases.This feature is seconded. Basically it would be useful to have a modifier which allows internal modification but disallows public reassignment. By an example, letting "property" be the new key word, class Order { property $customer; } class Order { private $customer; public getCustomer(){return $this->customer;} } $order->customer and $order->getCustomer() could have the same semantics in that a "copy of the pointer" in C terms is returned and you cannot call $order- >customer = null any more than you could call $order->getCustomer() = null. However, $customer itself should be modifyable, for instance, $order->customer- >id = 1000, if id is declared as public. This would be more in tune of mat dot barrie at gmail dot com and very useful in OOP. Inside the class, I would prefer to be able to reassign customer at will (even after constructor). Syntactically it would be nice to chose a syntax that would allow support for setters also, but for now, I would be happy with this. It sorta does the same thing as the __get() trick but does not mess up IDE support and will probably execute faster.