<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:series="http://unfoldingneurons.com/"
		>
<channel>
	<title>Comments on: Superglobals In Classes: Revisited</title>
	<atom:link href="http://www.brandonsavage.net/superglobals-in-classes-revisited/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.brandonsavage.net/superglobals-in-classes-revisited/</link>
	<description>The personal blog of Brandon Savage. Contains entries of a personal and professional nature focusing on PHP, Apple, LAMP, MySQL and Washington, DC.</description>
	<lastBuildDate>Fri, 03 Feb 2012 19:36:33 -0500</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<item>
		<title>By: fqqdk</title>
		<link>http://www.brandonsavage.net/superglobals-in-classes-revisited/#comment-628</link>
		<dc:creator>fqqdk</dc:creator>
		<pubDate>Fri, 17 Jul 2009 13:41:59 +0000</pubDate>
		<guid isPermaLink="false">http://www.brandonsavage.net/?p=460#comment-628</guid>
		<description>This snippet still has some problems...

$ValidUser = new VerifyLogin($_POST[&#039;username&#039;], $_POST[&#039;password&#039;]);
if($validUser) //...

First: now that you modified the method to not be a constructor, the construction could should be updated too:
  $ValidUser = new VerifyLogin();
  //...
Second: you have the variable name starting with different cases: you have $ValidUser assigned to your VerifyLogin instance and you check for $validUser in the conditional.

Third: after you fix the variable name, the condition will always evaluate to true because $ValidUser is an object, and that would impose some very serious security problems :D The condition should be spelled
if($ValidUser-&gt;verifyCredentials($_POST[&#039;username&#039;], $_POST[&#039;password&#039;]) //...

Fourth: even the variable name is misleading. After moving the authentication logic from the constructor to the verifyCredentials method $ValidUser does not at all denote a valid user! That name should be changed.

And the last problem is what Dave already mentioned, I will not repeat him. This problem is related to what you write in your recent article (the one about multiple levels of inheritance). The authentication process should be separated from the actual representation of users. The statement VerifyLogin IS A User does not make sense at all!

I would advise that you review your articles more thoroughly. Clueless noobs may find them, and without the same background as seasoned veterans they might take your code or worse your flawed concepts for granted, and replicate it in their designs! I actually found this post through the feed of Planet PHP, and given that popularity is power, the Spiderman principle should apply :)</description>
		<content:encoded><![CDATA[<p>This snippet still has some problems&#8230;</p>
<p>$ValidUser = new VerifyLogin($_POST['username'], $_POST['password']);<br />
if($validUser) //&#8230;</p>
<p>First: now that you modified the method to not be a constructor, the construction could should be updated too:<br />
  $ValidUser = new VerifyLogin();<br />
  //&#8230;<br />
Second: you have the variable name starting with different cases: you have $ValidUser assigned to your VerifyLogin instance and you check for $validUser in the conditional.</p>
<p>Third: after you fix the variable name, the condition will always evaluate to true because $ValidUser is an object, and that would impose some very serious security problems :D The condition should be spelled<br />
if($ValidUser-&gt;verifyCredentials($_POST['username'], $_POST['password']) //&#8230;</p>
<p>Fourth: even the variable name is misleading. After moving the authentication logic from the constructor to the verifyCredentials method $ValidUser does not at all denote a valid user! That name should be changed.</p>
<p>And the last problem is what Dave already mentioned, I will not repeat him. This problem is related to what you write in your recent article (the one about multiple levels of inheritance). The authentication process should be separated from the actual representation of users. The statement VerifyLogin IS A User does not make sense at all!</p>
<p>I would advise that you review your articles more thoroughly. Clueless noobs may find them, and without the same background as seasoned veterans they might take your code or worse your flawed concepts for granted, and replicate it in their designs! I actually found this post through the feed of Planet PHP, and given that popularity is power, the Spiderman principle should apply :)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Brandon Savage&#8217;s Blog: Superglobals In Classes: Revisited &#124; DreamNest - Technology &#124; Web &#124; Net</title>
		<link>http://www.brandonsavage.net/superglobals-in-classes-revisited/#comment-604</link>
		<dc:creator>Brandon Savage&#8217;s Blog: Superglobals In Classes: Revisited &#124; DreamNest - Technology &#124; Web &#124; Net</dc:creator>
		<pubDate>Tue, 14 Jul 2009 16:00:29 +0000</pubDate>
		<guid isPermaLink="false">http://www.brandonsavage.net/?p=460#comment-604</guid>
		<description>[...] an earlier post dealing with superglobals and classes, Brandon Savage looks at an example of why its still a bad idea.   I asserted at the time that superglobals inside of a class violated [...]</description>
		<content:encoded><![CDATA[<p>[...] an earlier post dealing with superglobals and classes, Brandon Savage looks at an example of why its still a bad idea.   I asserted at the time that superglobals inside of a class violated [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Gyorgy</title>
		<link>http://www.brandonsavage.net/superglobals-in-classes-revisited/#comment-603</link>
		<dc:creator>Gyorgy</dc:creator>
		<pubDate>Tue, 14 Jul 2009 14:30:24 +0000</pubDate>
		<guid isPermaLink="false">http://www.brandonsavage.net/?p=460#comment-603</guid>
		<description>Good point, I&#039;d like that every developer would use OOP powers to the max, because
superglobals in classes renders useless one of the basic principles of OOP (code isolation)</description>
		<content:encoded><![CDATA[<p>Good point, I&#8217;d like that every developer would use OOP powers to the max, because<br />
superglobals in classes renders useless one of the basic principles of OOP (code isolation)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave</title>
		<link>http://www.brandonsavage.net/superglobals-in-classes-revisited/#comment-602</link>
		<dc:creator>Dave</dc:creator>
		<pubDate>Tue, 14 Jul 2009 10:21:34 +0000</pubDate>
		<guid isPermaLink="false">http://www.brandonsavage.net/?p=460#comment-602</guid>
		<description>You&#039;ve just switched your dependancy from the global variable to an SQL table leaving the fundamental problem unaddressed.

The real problem is that the OO model you&#039;ve chosen isn&#039;t very sensible. Why should verifyLogin be an object? Personally I would have an AuthenticationHandler which is responsible for maintaining the global state. This could be an interface with site specific implementations but it maps much better to the necesary global state because you can at least make it a singleton.</description>
		<content:encoded><![CDATA[<p>You&#8217;ve just switched your dependancy from the global variable to an SQL table leaving the fundamental problem unaddressed.</p>
<p>The real problem is that the OO model you&#8217;ve chosen isn&#8217;t very sensible. Why should verifyLogin be an object? Personally I would have an AuthenticationHandler which is responsible for maintaining the global state. This could be an interface with site specific implementations but it maps much better to the necesary global state because you can at least make it a singleton.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Artur Ejsmont</title>
		<link>http://www.brandonsavage.net/superglobals-in-classes-revisited/#comment-601</link>
		<dc:creator>Artur Ejsmont</dc:creator>
		<pubDate>Tue, 14 Jul 2009 08:18:16 +0000</pubDate>
		<guid isPermaLink="false">http://www.brandonsavage.net/?p=460#comment-601</guid>
		<description>Although refactoring makes sense and code seems better now, you are not escaping user name any more .... its like asking for injections. 

Art</description>
		<content:encoded><![CDATA[<p>Although refactoring makes sense and code seems better now, you are not escaping user name any more &#8230;. its like asking for injections. </p>
<p>Art</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Christer</title>
		<link>http://www.brandonsavage.net/superglobals-in-classes-revisited/#comment-600</link>
		<dc:creator>Christer</dc:creator>
		<pubDate>Tue, 14 Jul 2009 05:40:24 +0000</pubDate>
		<guid isPermaLink="false">http://www.brandonsavage.net/?p=460#comment-600</guid>
		<description>You should probably fix the security holes as well since many beginners might use the code anyway, regardless of the warning in the bottom of the post, and they wouldn&#039;t have any knowledge on how to fix the security flaws...</description>
		<content:encoded><![CDATA[<p>You should probably fix the security holes as well since many beginners might use the code anyway, regardless of the warning in the bottom of the post, and they wouldn&#8217;t have any knowledge on how to fix the security flaws&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daniel O'Connor</title>
		<link>http://www.brandonsavage.net/superglobals-in-classes-revisited/#comment-598</link>
		<dc:creator>Daniel O'Connor</dc:creator>
		<pubDate>Tue, 14 Jul 2009 01:09:51 +0000</pubDate>
		<guid isPermaLink="false">http://www.brandonsavage.net/?p=460#comment-598</guid>
		<description>I&#039;d still do this differently, because you&#039;ve still got global state.

class DBAuthenticator {
   /** @param resource $db The database connection to use, which is a dependency */
   public function __construct($db) {}

   /** 
    * @return int User ID 
    * @throws Exception No such user
    * @throws Exception Invalid login
    */
   public function authenticate($user, $pass) {}
}

class User {
   public $id;
}

// Setup
$user = new User();  // Your model/data structure
$storage = new DBStorage(); // A layer to load and populate your models
$security = new DBAuthenticator($db_connection);


// Wiring
$user-&gt;id = $security-&gt;authenticate($_POST[&#039;user&#039;], $_POST[&#039;pass&#039;]);
$user = $storage-&gt;load($user);

That neatly splits:
 * The authentication method (&quot;Are these credentials allowed to access my resources&quot;) from the user profile
 * The authentication backend (database) from the user profile model

Changing the security mechanism from DBAuthenticator to MockAuthenticator or LDAPAuthenticator is then trivial, too.</description>
		<content:encoded><![CDATA[<p>I&#8217;d still do this differently, because you&#8217;ve still got global state.</p>
<p>class DBAuthenticator {<br />
   /** @param resource $db The database connection to use, which is a dependency */<br />
   public function __construct($db) {}</p>
<p>   /**<br />
    * @return int User ID<br />
    * @throws Exception No such user<br />
    * @throws Exception Invalid login<br />
    */<br />
   public function authenticate($user, $pass) {}<br />
}</p>
<p>class User {<br />
   public $id;<br />
}</p>
<p>// Setup<br />
$user = new User();  // Your model/data structure<br />
$storage = new DBStorage(); // A layer to load and populate your models<br />
$security = new DBAuthenticator($db_connection);</p>
<p>// Wiring<br />
$user-&gt;id = $security-&gt;authenticate($_POST['user'], $_POST['pass']);<br />
$user = $storage-&gt;load($user);</p>
<p>That neatly splits:<br />
 * The authentication method (&#8220;Are these credentials allowed to access my resources&#8221;) from the user profile<br />
 * The authentication backend (database) from the user profile model</p>
<p>Changing the security mechanism from DBAuthenticator to MockAuthenticator or LDAPAuthenticator is then trivial, too.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Brandon Savage</title>
		<link>http://www.brandonsavage.net/superglobals-in-classes-revisited/#comment-597</link>
		<dc:creator>Brandon Savage</dc:creator>
		<pubDate>Tue, 14 Jul 2009 00:06:20 +0000</pubDate>
		<guid isPermaLink="false">http://www.brandonsavage.net/?p=460#comment-597</guid>
		<description>Your comment was just a bit behind my correction; you&#039;re 100% right that a constructor returns an object regardless of a return statement.</description>
		<content:encoded><![CDATA[<p>Your comment was just a bit behind my correction; you&#8217;re 100% right that a constructor returns an object regardless of a return statement.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jason Stubbs</title>
		<link>http://www.brandonsavage.net/superglobals-in-classes-revisited/#comment-596</link>
		<dc:creator>Jason Stubbs</dc:creator>
		<pubDate>Mon, 13 Jul 2009 23:39:16 +0000</pubDate>
		<guid isPermaLink="false">http://www.brandonsavage.net/?p=460#comment-596</guid>
		<description>The biggest &quot;security hole&quot; is that $validUser will always evaluate to true as it becomes an instance of VerifyLogin regardless of the constructor&#039;s return value... To make your point explicit, you should probably have the original verifyCredentials() function to take $username and $password as parameters.

Your point itself though is completely valid and I&#039;d even extend it to say that classes should not use _any_ global variable at all. Everything should be either passed in via a constructor/function or, in the case of cross-object internal data, stored in a static class variable.</description>
		<content:encoded><![CDATA[<p>The biggest &#8220;security hole&#8221; is that $validUser will always evaluate to true as it becomes an instance of VerifyLogin regardless of the constructor&#8217;s return value&#8230; To make your point explicit, you should probably have the original verifyCredentials() function to take $username and $password as parameters.</p>
<p>Your point itself though is completely valid and I&#8217;d even extend it to say that classes should not use _any_ global variable at all. Everything should be either passed in via a constructor/function or, in the case of cross-object internal data, stored in a static class variable.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Brandon Savage</title>
		<link>http://www.brandonsavage.net/superglobals-in-classes-revisited/#comment-595</link>
		<dc:creator>Brandon Savage</dc:creator>
		<pubDate>Mon, 13 Jul 2009 23:31:33 +0000</pubDate>
		<guid isPermaLink="false">http://www.brandonsavage.net/?p=460#comment-595</guid>
		<description>You&#039;re right; I&#039;ve fixed that error. Constructors cannot return things.</description>
		<content:encoded><![CDATA[<p>You&#8217;re right; I&#8217;ve fixed that error. Constructors cannot return things.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: fqqdk</title>
		<link>http://www.brandonsavage.net/superglobals-in-classes-revisited/#comment-594</link>
		<dc:creator>fqqdk</dc:creator>
		<pubDate>Mon, 13 Jul 2009 23:26:47 +0000</pubDate>
		<guid isPermaLink="false">http://www.brandonsavage.net/?p=460#comment-594</guid>
		<description>Why did the verifyCredentials() method turn into a constructor in the second snippet? It servers no purpose for the topic (superglobals in methods). It&#039;s confusing. Constructors should not do work. What does returning boolean values from a constructor do?

Aside of these things what you say is good and correct. Global state is evil. :)</description>
		<content:encoded><![CDATA[<p>Why did the verifyCredentials() method turn into a constructor in the second snippet? It servers no purpose for the topic (superglobals in methods). It&#8217;s confusing. Constructors should not do work. What does returning boolean values from a constructor do?</p>
<p>Aside of these things what you say is good and correct. Global state is evil. :)</p>
]]></content:encoded>
	</item>
</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic (Feed is rejected)
Page Caching using disk: enhanced (User agent is rejected)
Database Caching 4/11 queries in 0.004 seconds using disk: basic
Content Delivery Network via Amazon Web Services: S3: files.brandonsavage.net.s3.amazonaws.com

Served from: www.brandonsavage.net @ 2012-02-07 04:34:57 -->
