[PHP] Two ways to obtain an object property
This relates to a minor dilemma I come across from time and time, and I'm looking for advice on pros and cons and best practice. Last night I encountered it again. Within a site I have a User object, and within page code would like to have if ($crntUser->isASubscriber) {...} There seems to be two ways to handle this: I can have a User object method "getSubscriberStatus()" which sets $this->isASubscriber. But to use this I would have to run the method just before the if statement. Or I could have a method "isASubscriber()" which returns the result, meaning the if statement should be if ($crntUser->isASubscriber()) {...} While this is last night's specific example, I seem to face the method-setting-variable or the method-returning-result-directly decision quite often. Is either of these approaches preferable, or does it simply not matter? Thanks Roddie Grant -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Two ways to obtain an object property
Hi, 2012/8/15 phplist > This relates to a minor dilemma I come across from time and time, and I'm > looking for advice on pros and cons and best practice. Last night I > encountered it again. > > Within a site I have a User object, and within page code would like to have > if ($crntUser->isASubscriber) {...} > > There seems to be two ways to handle this: > > I can have a User object method "getSubscriberStatus()" which sets > $this->isASubscriber. But to use this I would have to run the method just > before the if statement. > > Or I could have a method "isASubscriber()" which returns the result, > meaning the if statement should be > if ($crntUser->isASubscriber()) {...} > or you just set User::$isASubscriber before. or you can utilise __get() I don't really get the problem. You can for example set the property right after instanciation, or during instanciation (constructor). $this->isASubscriber = !empty($subscriptions); // or something like that Regards, Sebastian > > While this is last night's specific example, I seem to face the > method-setting-variable or the method-returning-result-**directly > decision quite often. > > Is either of these approaches preferable, or does it simply not matter? > > Thanks > > Roddie Grant > > -- > PHP General Mailing List (http://www.php.net/) > To unsubscribe, visit: http://www.php.net/unsub.php > >
Re: [PHP] How to catch an exception using SoapClient.
like any other exception ... using a try catch block ;) Ellis 110010100001 " Unfortunately, no one can be told what The Matrix is. You have to see it for yourself. " twitter.com/floverdevel facebook.com/ellis.antaya google.com/profiles/ellis.antaya linkedin.com/in/ellisantaya On Mon, Aug 6, 2012 at 10:56 PM, James Newman < james.new...@primalmedia.co.nz> wrote: > I was wondering how I'd catch an exception using SoapClient. > > > > $data = array( > 'Particular'=>'Payment for stuff', > 'Email' =>'e mail address', > 'CardNumber'=>', > 'CardType' =>'MC', > 'CardExpiry'=>'0423', > 'CardHolderName'=>'James Newman', > 'CardCSC' =>'111', > 'StoreCard' =>'true' > ); > $vars = array( > 'trace' => 1, > 'exceptions' => true, > 'cache_wsdl' => WSDL_CACHE_NONE, > 'features' => SOAP_SINGLE_ELEMENT_ARRAYS); > $client = new SoapClient("http://XMLSERVICEURLws/paymentws.asmx?WSDL";, > $vars); > > #$out = $client->ListCards($text); > #$this->_result = $client->ProcessPurchase($data); > $this->_result = $client->ProcessAuthorise($data); > #var_dump($client->__getLastRequestHeaders()); > #var_dump($client->__getTypes()); > print_r($this->_result); >
Re: [PHP] Reading class variable value always returns NULL
So here's some new observations on the instance variables being NULL. As far as we found out this is the sequence of events: 1. Apache (MPM) received request A which executes a php script. 2. Within this script during the unserialization of an object an exception is thrown. 3. This exception is catched and an error message is display to standard output with "echo". 4. The script ends normally and the standard output contents are returned in the HTTP response. 5. From now on this Apache worker is "tainted", meaning that every subsequent request will result in: 6. The same apache worker receives request B which executes a PHP script. 7. Within this PHP script reading instance variables will always return NULL, e.g.: foo = 1; // Now: $a->foo === NULL All subsequent requests to this apache worker will behave like this. The constellation leading to this behavior is very hard to further simplify. If we throw different exceptions, or unserialize different objects it doesn't happen anymore... As a workaround we added "exit;" to the end of our php script. With a call to "exit" the apache worker will not get "tainted"... Regards, Reto On Tue, Aug 14, 2012 at 11:52 PM, Reto Kaiser wrote: > Hey, > > We have: > error_reporting((E_ALL | E_STRICT) & ~(E_NOTICE | E_USER_NOTICE)); > > Displaying errors is disabled: > display_errors = Off > > We have a custom error handler which logs all errors to a file. > In this file we receive byeffect errors, like that the second argument > to "array_key_exists" should be array, but is NULL. When we further > debug the reason is that the second argument is an instance variable, > and all instance variables are NULL. > We're pretty sure this is a software bug, since it only happens from > time to time, and already happens in the first line of the php script, > when none of our application code was loaded. > For example: > > class A{} > $a = new A(); > $a->foo = 1; > if ($a->foo === null) { > throw new Exception("strange"); > } > > will throw an exception. > > Since it only happens from time to time, it is really hard to debug. > We're now trying to reproduce in a virtual machine environment, while > replaying the actual requests that our webserver received. When we're > just simulating random load on the web server it doesn't happen. So it > must have something to do with certain requests, and they must have > some strange byeffect on php, or mod_php or something related. > > Any input welcome! > > Thanks, > Reto > > On Tue, Aug 14, 2012 at 11:11 PM, Jim Lucas wrote: >> On 08/12/2012 05:32 AM, Reto Kaiser wrote: >>> >>> Hi, >>> >>> So I have this strange situation where I assign a classvariable a >>> value, but when I read the value it is NULL. >>> >>> Does anyone have an idea what could cause this, or how to further debug? >>> >>> Thanks, >>> Reto >>> >> >> What is your error reporting set to? >> >> Do you have display errors turned on? >> >> Are you saving your errors to a log file? >> >> -- >> Jim Lucas >> >> http://www.cmsws.com/ >> http://www.cmsws.com/examples/ -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Reading class variable value always returns NULL
As a little clarification: The Apache server in question is configured as a MPM prefork. On Wed, Aug 15, 2012 at 4:28 PM, Reto Kaiser wrote: > So here's some new observations on the instance variables being NULL. > As far as we found out this is the sequence of events: > > 1. Apache (MPM) received request A which executes a php script. > 2. Within this script during the unserialization of an object an > exception is thrown. > 3. This exception is catched and an error message is display to > standard output with "echo". > 4. The script ends normally and the standard output contents are > returned in the HTTP response. > 5. From now on this Apache worker is "tainted", meaning that every > subsequent request will result in: > > 6. The same apache worker receives request B which executes a PHP script. > 7. Within this PHP script reading instance variables will always > return NULL, e.g.: > > class A{} > $a = new A(); > $a->foo = 1; > // Now: $a->foo === NULL > > All subsequent requests to this apache worker will behave like this. > The constellation leading to this behavior is very hard to further > simplify. If we throw different exceptions, or unserialize different > objects it doesn't happen anymore... > > > As a workaround we added "exit;" to the end of our php script. With a > call to "exit" the apache worker will not get "tainted"... > > Regards, > Reto > > > > On Tue, Aug 14, 2012 at 11:52 PM, Reto Kaiser wrote: > > Hey, > > > > We have: > > error_reporting((E_ALL | E_STRICT) & ~(E_NOTICE | E_USER_NOTICE)); > > > > Displaying errors is disabled: > > display_errors = Off > > > > We have a custom error handler which logs all errors to a file. > > In this file we receive byeffect errors, like that the second argument > > to "array_key_exists" should be array, but is NULL. When we further > > debug the reason is that the second argument is an instance variable, > > and all instance variables are NULL. > > We're pretty sure this is a software bug, since it only happens from > > time to time, and already happens in the first line of the php script, > > when none of our application code was loaded. > > For example: > > > > > class A{} > > $a = new A(); > > $a->foo = 1; > > if ($a->foo === null) { > > throw new Exception("strange"); > > } > > > > will throw an exception. > > > > Since it only happens from time to time, it is really hard to debug. > > We're now trying to reproduce in a virtual machine environment, while > > replaying the actual requests that our webserver received. When we're > > just simulating random load on the web server it doesn't happen. So it > > must have something to do with certain requests, and they must have > > some strange byeffect on php, or mod_php or something related. > > > > Any input welcome! > > > > Thanks, > > Reto > > > > On Tue, Aug 14, 2012 at 11:11 PM, Jim Lucas wrote: > >> On 08/12/2012 05:32 AM, Reto Kaiser wrote: > >>> > >>> Hi, > >>> > >>> So I have this strange situation where I assign a classvariable a > >>> value, but when I read the value it is NULL. > >>> > >>> Does anyone have an idea what could cause this, or how to further > debug? > >>> > >>> Thanks, > >>> Reto > >>> > >> > >> What is your error reporting set to? > >> > >> Do you have display errors turned on? > >> > >> Are you saving your errors to a log file? > >> > >> -- > >> Jim Lucas > >> > >> http://www.cmsws.com/ > >> http://www.cmsws.com/examples/ >
Re: [PHP] Two ways to obtain an object property
On Wed, Aug 15, 2012 at 09:28:28AM +0100, phplist wrote: > This relates to a minor dilemma I come across from time and time, > and I'm looking for advice on pros and cons and best practice. Last > night I encountered it again. > > Within a site I have a User object, and within page code would like to have > if ($crntUser->isASubscriber) {...} > > There seems to be two ways to handle this: > > I can have a User object method "getSubscriberStatus()" which sets > $this->isASubscriber. But to use this I would have to run the method > just before the if statement. > > Or I could have a method "isASubscriber()" which returns the result, > meaning the if statement should be > if ($crntUser->isASubscriber()) {...} > > While this is last night's specific example, I seem to face the > method-setting-variable or the method-returning-result-directly > decision quite often. > > Is either of these approaches preferable, or does it simply not matter? If I read you correctly, the latter would be preferable, primarily because it involves one less step. But if you're going to have to make that decision in an "if" statement repeatedly, I'd probably say: $isSubscribed = $crntUser->isASubscriber(); just because in subsequent code, you're not suffering the (admittedly small) repeated overhead of the function call. But in answer to your question, isASubscriber() would be a pretty standard "getter" method to expose internal object properties. Paul -- Paul M. Foster http://noferblatz.com http://quillandmouse.com -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Two ways to obtain an object property
On Wed, Aug 15, 2012 at 11:33 AM, Paul M Foster wrote: > On Wed, Aug 15, 2012 at 09:28:28AM +0100, phplist wrote: > >> This relates to a minor dilemma I come across from time and time, >> and I'm looking for advice on pros and cons and best practice. Last >> night I encountered it again. >> >> Within a site I have a User object, and within page code would like to have >> if ($crntUser->isASubscriber) {...} >> >> There seems to be two ways to handle this: >> >> I can have a User object method "getSubscriberStatus()" which sets >> $this->isASubscriber. But to use this I would have to run the method >> just before the if statement. >> >> Or I could have a method "isASubscriber()" which returns the result, >> meaning the if statement should be >> if ($crntUser->isASubscriber()) {...} >> >> While this is last night's specific example, I seem to face the >> method-setting-variable or the method-returning-result-directly >> decision quite often. >> >> Is either of these approaches preferable, or does it simply not matter? > > If I read you correctly, the latter would be preferable, primarily > because it involves one less step. But if you're going to have to make > that decision in an "if" statement repeatedly, I'd probably say: > > $isSubscribed = $crntUser->isASubscriber(); > > just because in subsequent code, you're not suffering the (admittedly > small) repeated overhead of the function call. > > But in answer to your question, isASubscriber() would be a pretty > standard "getter" method to expose internal object properties. > > Paul I generally use this "getter" method as well. If it bothers the OP that isASubscriber() is a "method" rather than a "property," one could use the magic __get method: isASubscriber; } } } ?> In the end, it is still a function call either way though. The advantage I see to both of these method-based approaches versus exposing the property as public is that these methods prevent code outside your class from doing something stupid: isASubscriber = 'rutabaga'; // Fatal error: Cannot access private property User::$isASubscriber ?> (Yes, I have seen proof that it is TECHNICALLY possible to get around this in PHP, for example with unserialize.) Andrew -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] PHP session variables
On Fri, Aug 10, 2012 at 11:56 AM, Tedd Sperling wrote: > On Aug 10, 2012, at 11:45 AM, Tedd Sperling wrote: > >> On Aug 9, 2012, at 5:16 PM, Jim Lucas wrote: >>> You are relying on PHP's loose typing. This is a poor check. >>> >>> session_id() returns a string, not boolean. >>> >>> You should do this instead. >>> >>> if ( session_id() === '' ) >>> >>> >>> >>> -- >>> Jim Lucas >> >> Thanks Jim -- you're right. >> >> What about? >> >> if (!defined(SID)) >> { >> session_start(); >> } > > Before you answer, the "(!defined(SID))" is over 50 times slower than "( > session_id() === '' )" > > Your way is better. > > Cheers, > > tedd tedd, I think this is because you passed SID to defined() as a constant rather than a string, so the if test always returns true. When I changed this to if (!defined('SID')) { session _start(); } it worked as expected, and I got much more similar results. I also added a call to session_destroy() between the two tests so that each loop initialized the session once. (In your test, the second loop never initializes the session since it was already started by the first loop.) This is your code with my modifications: '; session_start(); } } session_destroy(); $endtime = microtime(true); $totaltime = $endtime - $starttime; $totaltime = round($totaltime,5); echo "First in $totaltime seconds."; $starttime = microtime(true); // whatever you want timed, you do here. for($i=1; $i < 1000; $i++) { if (session_id() ==='') { echo __LINE__, '::session_start()'; session_start(); } } $endtime = microtime(true); $totaltime = $endtime - $starttime; $totaltime = round($totaltime,5); echo "Second in $totaltime seconds."; session_destroy(); ?> Andrew -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Two ways to obtain an object property
On Wed, Aug 15, 2012 at 1:28 AM, phplist wrote: > I can have a User object method "getSubscriberStatus()" which sets > $this->isASubscriber. But to use this I would have to run the method just > before the if statement. > > Or I could have a method "isASubscriber()" which returns the result, > meaning the if statement should be > if ($crntUser->isASubscriber()) {...} I assume that the decision isn't really about using a property versus a method but that determining the value of the property is costly. For these cases I add an internal private property to save the result of the costly computation and initialize it on the first call to the accessor method. class User { private $_isSubscriber = null; public function isSubscriber() { if ($this->_isSubscriber === null) { $this->_isSubscriber = ... call database or whatever takes so long ... } return $this->_isSubscriber; } } If this isn't the case and you really just want to know which API is nicer, any of the replies so far are acceptable. I favor accessor methods because it's easier to change the implementation without having to change all the places you access it. Peace, David
Re: [PHP] PHP session variables
On Aug 14, 2012, at 11:01 AM, Robert Cummings wrote: > > I'm not sure if you're making a joke, but your changes have no effect. You've > merely explicitly stated the optional parameter's default value. What I had > meant was to change the following: > > > $starttime = microtime(); > $startarray = explode(" ", $starttime); > $starttime = $startarray[1] + $startarray[0]; > > ?> > > To the following :) > > > $starttime = microtime( true ); > > ?> > > Cheers, > Rob. Rob: Again thanks. Sorry, I totally missed your point. In my "defense" I commonly use the value returned from microtime() as a string and not as a float. The code that followed my "microtime( false );" demo broke the string and recombined it into a float. So, when you said: Please see the current signature for microtime(): mixed microtime ([ bool $get_as_float = false ] ) I looked at that and said to myself, "Oh, I need to define it as 'false' " because I was using it as a sting. I completely overlooked your point that microtime() could return a float and thus no need to work with it as a string -- duh! The demo is fixed (I think): http://www.webbytedd.com/b/timed1/ Thanks, tedd _ t...@sperling.com http://sperling.com -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] PHP session variables
Andrew: Your points are well taken -- thanks. However, my only concern is given this: > for($i=1; $i < 1000; $i++) >{ >if (!defined('SID')) > { > echo __LINE__, '::session_start()'; > session_start(); > } >} The php manual ( http://us3.php.net/manual/en/function.session-start.php ) First Note states that session_start() must be called *before* anything sent to the Browser. So, to rewrite your code -- for($i=1; $i < 1000; $i++) { if (!defined('SID')) { session_start(); echo __LINE__, '::session_start()'; } } -- should work better, right? Cheers, tedd _ t...@sperling.com http://sperling.com -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] PHP session variables
On 12-08-15 03:19 PM, Tedd Sperling wrote: Rob: Again thanks. Sorry, I totally missed your point. In my "defense" I commonly use the value returned from microtime() as a string and not as a float. The code that followed my "microtime( false );" demo broke the string and recombined it into a float. So, when you said: Please see the current signature for microtime(): mixed microtime ([ bool $get_as_float = false ] ) I looked at that and said to myself, "Oh, I need to define it as 'false' " because I was using it as a sting. I completely overlooked your point that microtime() could return a float and thus no need to work with it as a string -- duh! The demo is fixed (I think): http://www.webbytedd.com/b/timed1/ Thanks, tedd I only pointed it out because I used to do exactly the same thing :) Cheers, Rob. -- E-Mail Disclaimer: Information contained in this message and any attached documents is considered confidential and legally protected. This message is intended solely for the addressee(s). Disclosure, copying, and distribution are prohibited unless authorized. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] PHP session variables
On Wed, Aug 15, 2012 at 3:24 PM, Tedd Sperling wrote: > Your points are well taken -- thanks. I've seen a lot of people code that way, so it's easy to miss. In your original code, that first statement was calling session_start() 1,000 times. This is because the first time through, SID is undefined so defined(SID) was equivalent to defined('SID') and both would have returned false. After the first session_start(), though, SID WAS defined, but would have had some pseudo-random session identifier as its value. As a result, the last 999 times through your loop, you were actually scanning the defined constants to see if there was one named something like '7cjubadsh5lkq80opemht2ea03'. Obviously, it would never exist. > However, my only concern is given this: > >> for($i=1; $i < 1000; $i++) >>{ >>if (!defined('SID')) >> { >> echo __LINE__, '::session_start()'; >> session_start(); >> } >>} > > The php manual ( http://us3.php.net/manual/en/function.session-start.php ) > > First Note states that session_start() must be called *before* anything sent > to the Browser. > > So, to rewrite your code -- > > for($i=1; $i < 1000; $i++) >{ >if (!defined('SID')) > { > session_start(); > echo __LINE__, '::session_start()'; > } >} > > -- should work better, right? > > Cheers, > > tedd Yes, that is more correct. I think we have output buffering enabled on most of our servers (a lot of our legacy stuff really depends on it) so I didn't notice any errors, but you are correct. You really don't need the echo lines that I added in your test at all though. I just threw it in there to be able to see when the function was being called. However, due to the nature of your test page you are still sending output from the first loop before you call session_start() in the second loop. To be absolutely correct, you'd have to remove those echo statements I added for debugging, store all of your timings in separate variables and then output them at the end of the script. Andrew -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Two ways to obtain an object property
On 08/15/2012 11:28 AM, phplist wrote: This relates to a minor dilemma I come across from time and time, and I'm looking for advice [...] Within a site I have a User object, and within page code would like to have if ($crntUser->isASubscriber) {...} [...] if ($crntUser->isASubscriber()) {...} [...] Is either of these approaches preferable, or does it simply not matter? It depends - how long/heavy is isASubscriber() - how often you need to check - how realtime you need the subscription status to be if isASubscriber() is long/heavy (say you need to wait for a long query), I would suggest to set an attribute and get you information from the attribute. Otherwise, you can safely use the method. If you have "realtime" constraints, you have no choice than use the method, wether it's long or not. Talking about "best practice", I would use: - $currentUser->isSubscriber - $currentUser->isSubscriber() It's a naming matter. -- RMA. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php