On Tue, 2007-10-09 at 12:40 -0400, Andrew Ballard wrote: > On 10/9/07, Robert Cummings <robert@xxxxxxxxxxxxx> wrote: > > $sucker = new TryToViolateEncapsulation(); > > $sucker = (array)$sucker; > > > > $keys = array_keys( $sucker ); > > $sucker[reset( $keys )] = 500; > > > > $sucker = serialize( (object)$sucker ); > > $sucker = 'O:25:"TryToViolateEncapsulation"'.substr( $sucker, 14 ); > > $sucker = unserialize( $sucker ); > > > > print_r( $sucker ); > > > > ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: > > > > Maybe next time you'll have a challenge for me ;) And don't whine about > > how I achieved what I did. > > > > > That's a bit disturbing. Ok, while we're bending things a bit, I'll > make it a *little* tougher. :-) > > class TryToViolateEncapsulation { > private $someInt = 0; > > const MAX_INT = 100; > const MIN_INT = 0; > > public function getSomeInt() { > return $this->someInt; > } > > public function setSomeInt($someInt) { > $success = false; // assume failure > $someInt = (int) $someInt; > if($this->isValid($someInt)) { > $this->someInt = $someInt; > $success = true; > } else { > throw new InvalidArgumentException('Invalid value passed to > setSomeInt'); > } > > return $success; > } > > private function isValid($someInt) { > $isValid = true; > if($someInt < TryToViolateEncapsulation::MIN_INT || $someInt > > TryToViolateEncapsulation::MAX_INT) { > $isValid = false; > } > return $isValid; > } > > public function __wakeup() { > $this->setSomeInt($this->someInt); > } > } class Tricky extends TryToViolateEncapsulation { function __wakeup() { } function bleh( TryToViolateEncapsulation $obj ) { echo 'Gotta love it!!'."\n"; } } function objectCast( &$object, $class ) { $newObject = 'O:'.strlen( $class ).':"'.$class.'"' .substr( serialize( (object)(array)$object ), 14 ); $newObject = unserialize( $newObject ); $object = $newObject; } function arraySetPrivateField( &$objectArray, $className, $fieldName, $value ) { $objectArray["\x00$className\x00$fieldName"] = $value; } $sucker = new TryToViolateEncapsulation(); $sucker = (array)$sucker; arraySetPrivateField( $sucker, 'TryToViolateEncapsulation', 'someInt', 300 ); objectCast( $sucker, 'Tricky' ); print_r( $sucker ); $sucker->bleh( $sucker ); :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Certainly you'll notice I've extended the original class, overriden the __wakeup() call and basically used inheritance and polymorphism to my advantage. The object is now of a different class but will serve in all contexts that one expects the parent class unless an explicit class type check is made. I think it's sufficient though since I've still modified the private member variable of the parent ;) > Of course, my gripe with __wakeup is that it is essentially a PHP > implementation function that, IMO, should be private. However, it must > be declared public for it to work, and that means that anyone outside > the class can call it whenever they want. > > While I'm not totally sold on OOP for web pages, I still like PHP5 > because of the OO enhancements over PHP4. Can you code without them? > Sure. I can cut my grass with a push mower, too -- but I tend to like > my lawn tractor much better. > > However, thank you for demonstrating that I need to be MUCH more > careful when building objects to validate member values each time they > are used, and not just when they are set. I would argue that this kind of tampering isn't worth checking for on every unserialize. Cheers, Rob. -- ........................................................... SwarmBuy.com - http://www.swarmbuy.com Leveraging the buying power of the masses! ........................................................... -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php