<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
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:slash="http://purl.org/rss/1.0/modules/slash/"
xmlns:series="http://unfoldingneurons.com/"
><channel><title>Larry Ullman &#187; PHP</title> <atom:link href="http://www.larryullman.com/category/php/feed/" rel="self" type="application/rss+xml" /><link>http://www.larryullman.com</link> <description>Translating Geek Into English</description> <lastBuildDate>Mon, 21 May 2012 11:03:07 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <item><title>What is Larry Thinking? #55 =&gt; Good Companies, Books, and Answers</title><link>http://www.larryullman.com/2012/05/21/what-is-larry-thinking-55-good-companies-books-answers/</link> <comments>http://www.larryullman.com/2012/05/21/what-is-larry-thinking-55-good-companies-books-answers/#comments</comments> <pubDate>Mon, 21 May 2012 11:03:07 +0000</pubDate> <dc:creator>Larry</dc:creator> <category><![CDATA[JavaScript]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Web Development]]></category> <category><![CDATA[book]]></category> <category><![CDATA[hosting]]></category> <category><![CDATA[newsletter]]></category> <category><![CDATA[oop]]></category> <category><![CDATA[regex]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=3199</guid> <description><![CDATA[In this edition… About This Newsletter What Were You Thinking? =&#62; Ajax and Search Engines On the Web =&#62; My Web Host, ServInt On the Web =&#62; 37 Tested PHP, Perl, and JavaScript Regular Expressions On the Blog =&#62; Review of &#8220;Technical Blogging&#8221; by Antonio Cangiano Q&#38;A =&#62; Have You Changed Your Opinion of OOP? [...]]]></description> <content:encoded><![CDATA[<p>In this edition…</p><ul><li><a
href="http://www.larryullman.com/2012/05/21/what-is-larry-thinking-55-good-companies-books-answers/#about">About This Newsletter</a></li><li><a
href="http://www.larryullman.com/2012/05/21/what-is-larry-thinking-55-good-companies-books-answers/#you">What Were You Thinking? =&gt; Ajax and Search Engines</a></li><li><a
href="http://www.larryullman.com/2012/05/21/what-is-larry-thinking-55-good-companies-books-answers/#web1">On the Web =&gt; My Web Host, ServInt</a></li><li><a
href="http://www.larryullman.com/2012/05/21/what-is-larry-thinking-55-good-companies-books-answers/#web2">On the Web =&gt; 37 Tested PHP, Perl, and JavaScript Regular Expressions</a></li><li><a
href="http://www.larryullman.com/2012/05/21/what-is-larry-thinking-55-good-companies-books-answers/#blog">On the Blog =&gt; Review of &#8220;Technical Blogging&#8221; by Antonio Cangiano</a></li><li><a
href="http://www.larryullman.com/2012/05/21/what-is-larry-thinking-55-good-companies-books-answers/#qa1">Q&amp;A =&gt; Have You Changed Your Opinion of OOP?</a></li><li><a
href="http://www.larryullman.com/2012/05/21/what-is-larry-thinking-55-good-companies-books-answers/#qa2">Q&amp;A =&gt; Why does false equal 0?</a></li><li><a
href="http://www.larryullman.com/2012/05/21/what-is-larry-thinking-55-good-companies-books-answers/#news">Larry Ullman&#8217;s Book News =&gt; &#8220;PHP Advanced and Object-Oriented Programming</a></li></ul><p><span
id="more-3199"></span></p><h2 id="about">About This Newsletter</h2><p>So, in case you hadn&#8217;t noticed (or are new to the newsletter), it now has a new template. It&#8217;s a bit more involved than the previous template (two columns instead of just one), but is simpler in other ways, too. The new look will more closely match the updated scheme for <a
href="http://LarryUllman.com">LarryUllman.com</a>, whenever I get around to putting that online (aka, July). Basically what I&#8217;m going with for the updated site is a white background, minimum of images, blue for headings, and, above all, a clear presentation of content.</p><p>To create this newsletter template, I used the template builder from <a
href="http://campaignmonitor.com.">Campaign Monitor</a>, whom I use for these newsletters. Campaign Monitor costs me $30/month (US), but I really think it&#8217;s worth it. They have a good product, and the user interface they&#8217;ve created is tremendous. In any case, I&#8217;m hoping that since I used their system, the resulting template will look reasonably good on most systems and devices.</p><p>As always, questions, comments, and all feedback are much appreciated. And thanks for your interest in what I have to say and do!</p><h2 id="you">What Were You Thinking? =&gt; Ajax and Search Engines</h2><p>In my <a
href="http://www.larryullman.com/2012/04/30/what-is-larry-thinking-54-salt-pepper-99designs/#qa1">previous newsletter</a>, I answered a question about making Ajax-derived content available to search engines. Yogesh was kind enough to share a link at <a
href="https://developers.google.com/webmasters/ajax-crawling/">Google Developers</a> in which Google explains what else you can do to make Ajax-derived content indexable. Thanks, Yogesh!</p><h2 id="web1">On the Web =&gt; My Web Host, ServInt</h2><p>Since I&#8217;m dishing out accolades (e.g., Campaign Monitor), I&#8217;d like to recognize the company I use for Web hosting: <a
href="http://www.servint.net">ServInt</a>. I&#8217;ve been using ServInt for my Web hosting for almost five years now and I&#8217;m so, so happy with their service. They only provide Virtual Private Servers (VPS) and dedicating hosting, so ServInt is not for everyone. But I think their packages are reasonably priced and their customer service is excellent. Their customer service is excellent! I&#8217;m paying $50 (USD) per month and am happily doing so. I have complete control over my little area of the server and don&#8217;t have to worry about what someone else might have done that would bring my site down. I have a few sites on the server, which garner between 500,000 and 1 million page views per month, and the lowest-level Essential VPS setup handles that easily.</p><p>There are two reasons I&#8217;m mentioning ServInt now. One is that I get asked this question a lot. Although if you&#8217;re not interested in a VPS account, these companies have also been recommended in my <a
href="http://www.larryullman.com/forums/index.php?/topic/132-web-hosting-recommendation/">forums</a>:</p><ul><li><a
href="http://www.dreamhost.com">Dreamhost</a></li><li><a
href="http://www.hostduplex.com">HostDuplex</a></li><li><a
href="http://hostgator.com">HostGator</a></li></ul><p>Besides letting you all know about a good hosting company, if you&#8217;re looking for one, I wanted to thank the people that have used me as a reference when creating his or her own account with ServInt. I don&#8217;t know who has done so, but a couple of people have signed up with ServInt and mentioned me in the past few months, which gives me a small credit on my account. Thanks for that!</p><h2 id="web2">On the Web =&gt; 37 Tested PHP, Perl, and JavaScript Regular Expressions</h2><p>Some time ago I stumbled upon <a
href="http://www.virtuosimedia.com/dev/php/37-tested-php-perl-and-javascript-regular-expressions">37 Tested PHP, Perl, and JavaScript Regular Expressions</a>. This is just a list of 37 Perl-Compatible Regular Expressions (PCRE) that you can use for common purposes: credit card numbers, dates, postal codes, URLs, email addresses, and more. A good resource to have around!</p><h2 id="blog">On the Blog =&gt; Review of &#8220;Technical Blogging&#8221; by Antonio Cangiano</h2><p>I <a
href="http://www.larryullman.com/2012/05/07/review-of-technical-blogging-by-antonio-cangiano/">just recently reviewed</a> the book &#8220;<a
href="http://amzn.to/H6gFcE">Technical Blogging</a>&#8221; by <a
href="http://antoniocangiano.com/">Antonio Cangiano</a>. It&#8217;s a very good book, and one that I&#8217;m happy that I read. For more, check out the <a
href="http://www.larryullman.com/2012/05/07/review-of-technical-blogging-by-antonio-cangiano/">review on my blog</a>.</p><h2 id="qa1">Q&amp;A =&gt; Have You Changed Your Opinion of OOP?</h2><p>In response to my previous newsletter, Marten asked if I have changed my opinion about procedural vs. object-oriented programming. I suspect the question was raised in part because I&#8217;m currently working on &#8220;<a
href="http://amzn.to/M6yvzg">PHP Advanced and Object-Oriented Programming: Visual QuickPro Guide</a>&#8220;. This is something I&#8217;ve discussed in the past, and am happy to go through again. The short answer is no, I have not changed my opinion. And here is what that opinion is:</p><blockquote><p>Procedural programming is better in some situations and OOP is better in some situations.</p></blockquote><p>This is an interesting debate, because PHP is one of the few programming languages that allows you to work procedurally or objectively. You can&#8217;t do procedural code with Java, JavaScript, or Ruby, and you can&#8217;t use objects with C. In PHP, you can <em>choose</em> to use objects or not use objects.</p><p>As for myself, obviously if I&#8217;m using JavaScript, Ruby, or ActionScript, I&#8217;m going to use objects. If I&#8217;m doing C, I&#8217;m not. On some PHP projects, I&#8217;ll use procedural code. On other PHP projects, I&#8217;ll use objects. Obviously any project I do that uses the <a
href="http://www.yiiframework.com">Yii framework</a> will use objects, as most frameworks are OOP in nature. So I&#8217;m totally comfortable with both approaches and I have no preference for one over the other, I always just try to choose the right tool for the job.</p><p>That, of course, is what we should all be doing as developers. There are very few absolutes when it comes to programming; there&#8217;s mostly just opinions. I&#8217;m sure that part of the reason it may have seemed like I didn&#8217;t care for OOP is that I don&#8217;t care for the presumption that OOP is better than procedural programming. OOP has its strengths and weaknesses, as does procedural programming. One is not categorically better or worse than the other. In PHP, which allows for both, there&#8217;s a very strong argument to being comfortable with both approaches so that you, too, can choose the right tool for each job.</p><p>This belief of mine also applies to frameworks. People who are really intro frameworks sometimes assert that programming with frameworks is vastly superior. It&#8217;s not. Not all the time, that is. For some developers, with some projects, a framework is the better choice. For some developers, with some projects, a framework would be the worse choice.</p><p>I like analogies, so I&#8217;ll end this with one: I like tools, I like working around the house and being handy. I have probably about 30 screwdrivers and four electric drill/drivers, including a relatively new, and quite powerful, impact driver. The analogy is that this impact driver (OOP) is the better way to drive a screw, but that&#8217;s patently false. The driver was much more expensive than any screwdriver, and it&#8217;s much heavier, and I need to go looking for the right bit, and I need to keep the batteries charged. And aside from all that, if I had to put a small screw into the back of a picture frame, the impact driver would be a <em>terrible</em> choice. But the same goes for the screwdriver (procedural): if I had to drive a three-inch lag bolt into a post, trying to do that with a screwdriver would be a decision I&#8217;d regret for a long, long time.</p><p>Do away with the assumptions, learn as much as you can, and always try to choose the right tool for the job.</p><h2 id="qa2">Q&amp;A =&gt; Why does false equal 0?</h2><p>Matti sent me this question via Twitter, specifically wondering what the difference is between 0 and 1 and true and false in PHP, and why false equals 0. This is a common point of confusion and cause of many bugs. However, the issue isn&#8217;t with the differences between these values but rather with how conditionals are evaluated and what equality is.</p><p>When you write any conditional in PHP, PHP needs to determine whether that conditional is true or false. For many conditionals, such as comparison, it&#8217;s pretty easy to identify true/false: is <strong>$x</strong> greater than 5 or no? Other conditionals are more subjective, though, and the language needs to define its rules for these situations. For example, <code>if ($x) {</code>. Is that conditional true or false? Well, it depends upon the value of <strong>$x</strong>, of course.</p><p>Obviously, if <strong>$x</strong> has a value of <strong>true</strong>, then the conditional is true. The same goes for <strong>$x</strong> having a value of &#8220;something&#8221;. It&#8217;s also pretty easy to decide that null is going to be treated as false. Things get tricky, though, when you have values such as 0 and an empty string. If <code>$x = 0;</code>, then should that conditional be true or false? The variable has been deliberately assigned a value, but the value is 0. Again, these are the kinds of choices that creators of a language have to make. In PHP, 0, an empty string, false, and null are all considered <em>empty</em> values, which get evaluated as false when used as the basis of a conditional.</p><p>Similarly, language designers have to make decisions as to what constitutes equality. If you compare two values of the same type—a string against a string, a number against a number, it is again easy to evaluate equality. It gets complicated when you compare values of different types: <code>if (2 == "2")</code>. That conditional compares the number 2 against the string &#8220;2&#8243;. These two values are not <em>identical</em> because of their different types, but are they equal?</p><p>To compare two different types, languages have to cast (i.e., forcibly convert) one type to the other. Generally, casting converts a value down to a simpler type. In that conditional, PHP will convert the string &#8220;2&#8243; to its numeric equivalent, which is 2. When you compare a Boolean against a non-Boolean, the non-Boolean has to be casted to a Boolean. As we&#8217;ve already seen, the empty values are treated as false in a conditional, so those values—0, an empty string, null, and false—are cast to the Boolean <strong>false</strong>. Hence, 0 does equal <strong>false</strong>.</p><p>Fortunately, programming languages tend to be pretty consistent in what gets treated as false (JavaScript also equates 0, an empty string, null, and false). The bugs arise in situations where your code tests for &#8220;truthiness&#8221; when it shouldn&#8217;t. For example, the conditional <code>if ($x) {</code> is fine unless one of the empty values is a valid value for <strong>$x</strong>. If it&#8217;s okay for <strong>$x</strong> to have a value of an empty string, you&#8217;d need to change your conditional accordingly. In PHP, the <strong>empty()</strong> function can discern between a variable just being set (i.e., assigned a value), and having a non-empty value. As another example, the <strong>strpos()</strong> function in PHP looks for a needle in a haystack, returning the starting indexed position where the needle is found. If the needle is found at the very beginning of the haystack, then the function will return 0. If you were to do this, you&#8217;d have a bug:</p><blockquote><p><code>if (strpos($haystack, $needle)) {</code></p></blockquote><p>The assumption is that the condition will be true if the needle is found in the haystack, but as written, the condition will only be true if the needle is found in the haystack <em>but not as the first thing in the haystack</em>. The proper way to write that conditional is:</p><blockquote><p><code>if (strpos($haystack, $needle) !== false) {</code></p></blockquote><p>Also note that it&#8217;s an identity comparison to false, because using != contains the same bug, as 0 does equal false.</p><p>Thanks to Matti for the good question. I hope this has clarified the issue and please, anyone, let me know if you have more questions or comments about this or similar matters.</p><h2 id="news">Larry Ullman&#8217;s Book News =&gt; &#8220;PHP Advanced and Object-Oriented Programming&#8221;</h2><p>First, I continue to receive a lot of positive feedback on the &#8220;<a
href="http://www.larryullman.com/books/modern-javascript-develop-and-design/">Modern JavaScript: Develop and Design</a>&#8221; book, which makes me very happy. I&#8217;ve posted a couple of the comments <a
href="http://www.larryullman.com/books/modern-javascript-develop-and-design/reviews/">on my Web site</a>, and currently the book has received five reviews on <a
href="http://amzn.to/wsdmkq">Amazon</a>, all for five stars. The book seems to be selling well, too, which is great, but knowing that I was able to do what I set out to do—and that my intention actually did match up with what readers wanted—is paramount. My continued thanks to everyone for their interest in the book and for the nice words on it.</p><p>Right now, I&#8217;m continuing to chug away on the third edition of my PHP advanced book, titled &#8220;<a
href="http://amzn.to/M6yvzg">PHP Advanced and Object-Oriented Programming: Visual QuickPro Guide</a>&#8220;. I&#8217;ve written four chapters thus far and hope to get another two written before I head off to Istanbul (in 10 days!).</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2012/05/21/what-is-larry-thinking-55-good-companies-books-answers/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Working with Layouts in Yii</title><link>http://www.larryullman.com/2012/05/16/working-with-layouts-in-yii/</link> <comments>http://www.larryullman.com/2012/05/16/working-with-layouts-in-yii/#comments</comments> <pubDate>Wed, 16 May 2012 11:00:20 +0000</pubDate> <dc:creator>Larry</dc:creator> <category><![CDATA[PHP]]></category> <category><![CDATA[Web Development]]></category> <category><![CDATA[framework]]></category> <category><![CDATA[mvc]]></category> <category><![CDATA[yii]]></category> <category><![CDATA[yiiframework]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=3196</guid> <description><![CDATA[Using the Model-View-Controller (MVC) design pattern, the look of a Yii-based site is naturally controlled by the View files. These files are a combination of HTML and PHP that help to create the desired output. Specific pages in a site will use specific View files. In fact, the View files are designed to be broken [...]]]></description> <content:encoded><![CDATA[<p>Using the <a
href="http://en.wikipedia.org/wiki/Model–view–controller">Model-View-Controller (MVC)</a> design pattern, the look of a <a
href="http://www.yiiframework.com">Yii</a>-based site is naturally controlled by the View files. These files are a combination of HTML and PHP that help to create the desired output. Specific pages in a site will use specific View files. In fact, the View files are designed to be broken down quite atomically, such that, for example, the form used to both create and edit an employee record is its own file, and that file can be included by both <strong>create.php</strong> and <strong>update.php</strong>. As with most things in OOP, implementing atomic, <a
href="http://ezinearticles.com/?The-Importance-of-Decoupled-Objects-in-OOP&amp;id=4073112">decoupled</a> functionality goes a long way towards improving reusability. But the individual View files are only part of the equation for rendering a Web page. Individual view files get rendered within a <em>layout</em> file. And although I&#8217;ve mentioned layouts a time or two in my writings on Yii, it&#8217;s a subject that deserves its own post.<span
id="more-3196"></span></p><p>To be clear, layouts <em>are</em> a type of View file. Specifically, whereas other View files get placed within a directory for the corresponding Controller (i.e., the <strong>SiteController</strong> pulls from <strong>views/site</strong>), layout files go within <strong>views/layouts</strong>. But while the other View files are associated with individual Controllers (and therefore, individual pages), layouts are communal, shared by all the pages. Simply put, a layout file is the parent wrapper for the entire site&#8217;s templating system. I&#8217;ll explain&#8230;</p><h2>The Premise of Templates</h2><p>When you begin creating dynamic Web sites using PHP, you&#8217;ll quickly recognize that many parts of an HTML page will be repeated throughout the site. For example, the opening and closing HTML and BODY tags. Even the site you&#8217;re looking at now has repeating elements: the header, the navigation, the footer, etc. To create a template system, you would pull all of those common elements out and put them into one (or more) separate files. Then each specific page can include these files around the page-specific content:</p><pre class="brush: php; title: ; notranslate">include('header.html');
// Add page-specific content.
include('footer.html'); </pre><p>This is the approach I would use on non-framework-based sites. It&#8217;s easy to generate and maintain. If you need to change the header for the entire site, you only need to edit the one file.</p><h2>Templates in Yii</h2><p>When using a framework, you&#8217;ll probably end up with a &#8220;bootstrap&#8221; approach, where all of the pages are accessed through one file. In the case of Yii, that bootstrap file is <strong>index.php</strong>. Part of its job is to manufacture the necessary HTML for the requested resource. Whereas the non-framework approach pulls the template files into the page-specific file, Yii pulls all the files from includes and assembles them together. Of these files, the layout files constitute all the common elements; everything that&#8217;s not page-specific. If you look at a Yii-generated site, you&#8217;ll see that <strong>views/layouts/main.php</strong> begins with the DOCTYPE and opening HTML tag, then has the HTML HEAD and all its jazz, then starts the BODY, and finally has the footer material and the closing tags. In the middle of the body of the code, you&#8217;ll see this line:</p><pre class="brush: php; title: ; notranslate">&lt;!--?php echo $content; ?--&gt;</pre><p>This is a magic line as it pulls in the page-specific content. If the site you&#8217;re looking at now used Yii, the value of <strong>$content</strong> would be all the HTML that makes up this post you&#8217;re reading. For a Yii example, when the user is looking at <strong>site/login</strong>, the <strong>SiteController</strong>&#8216;s <strong>actionLogin()</strong> method will be called. That method will render the <strong>views/site/login.php</strong> View page, pulling that file&#8217;s contents into the main layout file at that <strong>echo $content</strong> location. That&#8217;s what&#8217;s going on behind the scenes.</p><p>So here, then, is the first key concept: if you want to change the general look of your Web site, edit the layout file (<strong>views/layouts/main.php</strong>). If you were to take your HTML mockup for your site, drop in the <strong>echo $content;</strong> line at the right place, and save it as <strong>views/layout/main.php</strong>, you will have created a custom look for your Web app. That is the basic principle and it&#8217;s essentially that simple.</p><p>To take layouts a step further, many sites will use variations on a theme. For example, the first Yii-based site I created used one header for the home page and another header for other pages, with all the remaining common elements being consistent. Or, I worked on an e-commerce project where one category of products used layout A and another category used layout B. If you have this need, there are a couple of ways of going about it.</p><h2>Creating a Second Layout</h2><p>The first and most obvious route is to create a second layout file. In the example where the site&#8217;s home page used a variation on the template, I created <strong>views/layouts/home.php</strong>. It was based upon <strong>main.php</strong>, with the necessary edits. To dynamically switch layouts, I changed the value assigned to the <strong>layout</strong> property within the proper Controller method:</p><pre class="brush: php; title: ; notranslate">// protected/controllers/SiteController.php
public function actionIndex() {
    $this-&gt;layout = 'home';</pre><p>And that&#8217;s all there is to it. When <strong>views/site/index.php</strong> would be rendered, it&#8217;d use the <strong>views/layouts/home.php</strong> template.</p><p>Although this approach is easy to understand and implement, it has a downside: a LOT of HTML is being repeated between the two layout files. If I needed to change the navigation, I had to edit both files in the same way. This leads us to option B.</p><h2>Hijacking the Content</h2><p>More recent versions of Yii will automatically create three layout files when you create a new Web app:</p><ul><li><strong>views/layouts/column1.php</strong></li><li><strong>views/layouts/column2.php</strong></li><li><strong>views/layouts/main.php</strong></li></ul><p>Although all three are layout files, you don&#8217;t have three different template files. The <strong>main.php</strong> file still creates the DOCTYPE and HTML and HEAD and so forth. The <strong>column1.php</strong> and <strong>column2.php</strong> files simply create variations on how the page-specific content gets rendered. These files do so by hijacking the layout process. For example, here is the entirety of <strong>column1.php</strong>:</p><pre class="brush: php; title: ; notranslate">&lt;!--?php $this---&gt;beginContent('//layouts/main'); ?&gt;&lt;/pre&gt;
&lt;div id=&quot;content&quot;&gt;&lt;/div&gt;
&lt;pre&gt;
&lt;!-- content --&gt;
&lt;!--?php $this---&gt;endContent(); ?&gt;</pre><p>Again, you have the magic <strong>echo $content </strong>line there, but all <strong>column1.php</strong> does is wrap the page-specific content in a DIV.</p><p>The <strong>column2.php</strong> file starts off the same, but adds another DIV (which includes some widgets) before <strong>$this-&gt;endContent()</strong>:</p><pre class="brush: php; title: ; notranslate">&lt;!--?php $this---&gt;beginContent('//layouts/main'); ?&gt;&lt;/pre&gt;
&lt;div class=&quot;span-19&quot;&gt;
&lt;div id=&quot;content&quot;&gt;&lt;/div&gt;
&lt;!-- content --&gt;&lt;/div&gt;
&lt;div class=&quot;span-5 last&quot;&gt;
&lt;div id=&quot;sidebar&quot;&gt;&lt;!--?php  $this---&gt;beginWidget('zii.widgets.CPortlet', array(
 'title'=&gt;'Operations',
 ));
 $this-&gt;widget('zii.widgets.CMenu', array(
 'items'=&gt;$this-&gt;menu,
 'htmlOptions'=&gt;array('class'=&gt;'operations'),
 ));
 $this-&gt;endWidget();
 ?&gt;&lt;/div&gt;
&lt;!-- sidebar --&gt;&lt;/div&gt;
&lt;pre&gt;
&lt;!--?php $this---&gt;endContent(); ?&gt;</pre><p>The trick here is the call to <strong>beginContent()</strong>. Remember how the layout file echoes the page-specific content in the correct place? Well, this call to <strong>beginContent()</strong> says that we&#8217;re about to start rendering the content. The method is provided with the primary layout file to use as the parent (i.e., the layout that encapsulates this content). All that&#8217;s happened here is that the content has been hijacked and replaced with slightly modified content. So the content in <strong>views/site/login.php</strong> gets pulled into <strong>column.php</strong>, where it&#8217;s wrapped within other content, and the combination of that content gets passed to <strong>main.php</strong>.</p><p>There are two tricks to this: first, <strong>beginContent()</strong> must point to <strong>//layouts/main.php</strong>. (The // just says to start in the Views directory.) Second, the layout that the Controller thinks it&#8217;s using is <strong>column1.php</strong>, not <strong>main.php</strong>. I personally think this approach is a bit complicated, particularly for the Yii newbie (yiibie?), but it is useful in situations where the content around the page-specific content needs to be adjusted dynamically.</p><p>If you were to open <strong>components/Controller.php</strong>, you would see this line:</p><pre class="brush: php; title: ; notranslate">public $layout='//layouts/column1';</pre><p>That one line says that all Controllers (which inherit from <strong>Controller</strong>) will use <strong>column1.php</strong> as its layout. If you were to change this one line to <em>column2</em>, then all Controllers would use that as the default layout. If you were to change this one line to <em>main</em>, then all Controllers would use <strong>main.php</strong> as the default layout, without the intermediary column layouts.</p><p>Again, this is a bit more convoluted than is healthy for newbies, but layouts are just wrappers to page-specific content, whether you use a single layout or intermediary layouts such as column1 and column2. If you&#8217;d like a visual representation, there&#8217;s a useful image provided among the <a
href="http://www.yiiframework.com/wiki/249/understanding-the-view-rendering-flow/#comments">comments in this article</a>.</p><h2>Quick Guide</h2><p>To summarize what&#8217;s been covered here&#8230;</p><p>To change the entire look for the entire site, edit <strong>layouts/main.php</strong>, but be sure to use the <strong>echo $content</strong> line where appropriate.</p><p>To change the default layout for every Controller, edit this line in <strong>components/Controller.php</strong>:</p><pre class="brush: php; title: ; notranslate">public $layout='//layouts/column1';</pre><p>To change the default layout for every View in an individual Controller, add this line to that Controller&#8217;s definition:</p><pre class="brush: php; title: ; notranslate">class SiteController extends Controller {
public $layout = 'column2';</pre><p>To change the layout used for a single action, add this line to the corresponding action:</p><pre class="brush: php; title: ; notranslate">// protected/controllers/SiteController.php
public function actionIndex() {
    $this-&gt;layout = 'home';</pre><p>And remember that <strong>column1.php</strong> and <strong>column2.php</strong> just hijack the page-specific content before it gets passed on to the <strong>main.php</strong> layout file.</p><p>I hope this post has been helpful and let me know if you have any questions or problems with layouts in Yii. (And by the way, if you like this post, I&#8217;m going to be writing a book on Yii later this summer. Subscribe to my newsletter or follow me on Twitter to stay tuned!)</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2012/05/16/working-with-layouts-in-yii/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>What&#8217;s New in PHP 5.4</title><link>http://www.larryullman.com/2012/05/09/whats-new-in-php-5-4/</link> <comments>http://www.larryullman.com/2012/05/09/whats-new-in-php-5-4/#comments</comments> <pubDate>Wed, 09 May 2012 11:00:21 +0000</pubDate> <dc:creator>Larry</dc:creator> <category><![CDATA[PHP]]></category> <category><![CDATA[Web Development]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=3130</guid> <description><![CDATA[So PHP 5.4 came out a little while back, and although there aren&#8217;t any major changes, there are a couple to be aware of. Most of the changes involve either very advanced PHP programming (e.g., closures now support the $this variable) or somewhat advanced Object-Oriented Programming. But there are a some changes that will affect the [...]]]></description> <content:encoded><![CDATA[<p>So PHP 5.4 came out a little while back, and although there aren&#8217;t any major changes, there are a <a
href="http://docs.php.net/manual/en/migration54.new-features.php  " class="broken_link">couple to be aware of</a>. Most of the changes involve either very advanced PHP programming (e.g., closures now support the <strong>$this</strong> variable) or somewhat advanced Object-Oriented Programming. But there are a some changes that will affect the average PHP programmer, which I&#8217;ll outline here.<span
id="more-3130"></span></p><h2>Short Array Syntax</h2><p>Historically in PHP, on used the <strong>array()</strong> function to create a new array, as in:</p><pre class="brush: php; title: ; notranslate">$empty = array();
$numbers = array(1, 2, 3, 4);
$states = array('AL' =&gt; 'Alabama', 'AK' =&gt; 'Alaska', 'AZ' =&gt; 'Arizona');</pre><p>PHP 5.4 now has the short array syntax, which just replaces calls to <strong>array()</strong> with the array operator:</p><pre class="brush: php; title: ; notranslate">$empty = [];
$numbers = [1, 2, 3, 4];
$states = ['AL' =&gt; 'Alabama', 'AK' =&gt; 'Alaska', 'AZ' =&gt; 'Arizona'];</pre><p>This is all good and fine, and matches what you might be doing in other languages (such as JavaScript), but remember that you can only do this as of PHP 5.4. This means that unless you know that any server you&#8217;ll be using your code on, now or in the future, must be running PHP 5.4 or later.</p><h2>&lt;?= Always Available</h2><p>In previous versions of PHP, if the short open tags setting was enabled, you could do this shortcut to print the value of a variable:</p><pre class="brush: php; title: ; notranslate">&lt;?=$some_var; ?&gt;</pre><p>Most commonly you&#8217;ll see this when using frameworks and templating tools. As of PHP 5.4, this is now always an option, even if short tags are disabled. The only thing to be careful of with this syntax is that it assumes that <strong>$some_var</strong> has a value.</p><h2>Built-in Web Server</h2><p>In my opinion, the coolest addition is the built-in <a
href="http://docs.php.net/manual/en/features.commandline.webserver.php" class="broken_link">web server in CLI mode</a>. In fact, I&#8217;ve already written about it in Chapter 12 of the third edition of my &#8220;<a
href="http://www.larryullman.com/2012/04/09/php-5-advanced-visual-quickpro-guide-3rd-edition-table-of-contents/">PHP Advanced: Visual QuickPro Guide</a>&#8220;, which I&#8217;m currently writing. PHP&#8217;s command-line interface (CLI) mode allows you to run PHP commands and PHP scripts from the command-line interface. As of PHP 5.4, that command-line tool also has a basic Web server that can be enabled, letting you test PHP scripts in a Web browser without using Apache or IIS or another Web server application. In short, it just became a bit easier to quickly test some PHP code.</p><h2>The session_status() Function</h2><p>PHP 5.4 introduces some new functions, constants, classes, and methods, but the one that most piques my interest is <strong>session_status()</strong>. This function returns a constant indicating the current session status:</p><ul><li><strong>PHP_SESSION_DISABLED</strong> if sessions are disabled.</li><li><strong>PHP_SESSION_NONE</strong> if sessions are enabled, but none exists.</li><li><strong>PHP_SESSION_ACTIVE</strong> if sessions are enabled, and one exists.</li></ul><p>I haven&#8217;t played with this yet myself, but imagine it could be a useful debugging tool, at the very least.</p><h2>Removed Features</h2><p>Finally, you should be aware that PHP 5.4 has removed several features that have been deprecated for some time. Off these, three are important (in that they used to be important):</p><ul><li>Safe mode is no longer supported</li><li>Magic Quotes does not exist (and the <strong>get_magic_quotes_gpc()</strong> function always returns false)</li><li>The <strong>register_globals</strong> directive has been removed</li></ul><p>With these three changes, you can officially no longer use features that you hopefully stopped using a long, long time ago.</p><p>So there you have the key changes in PHP 5.4, aside from some of the more esoteric things. The changes here aren&#8217;t nearly on the same scale as those introduced in PHP 5.1 (e.g. <a
href="http://docs.php.net/pdo" class="broken_link">PDO</a> extension enabled), 5.2 (e.g., <a
href="http://docs.php.net/manual/en/ref.filter.php" class="broken_link">Filter</a> and <a
href="http://docs.php.net/manual/en/ref.json.php" class="broken_link">JSON</a> extensions enabled), and 5.3 (e.g., <a
href="http://docs.php.net/manual/en/language.namespaces.php" class="broken_link">namespaces</a> and <a
href="http://docs.php.net/manual/en/functions.anonymous.php" class="broken_link">closures</a>, the <a
href="http://docs.php.net/manual/en/book.fileinfo.php" class="broken_link">Fileinfo</a> extension, the <a
href="http://docs.php.net/manual/en/book.intl.php" class="broken_link">INTL</a> extension), but it&#8217;s good that a language that&#8217;s been around for so long continues to get tweaked, even in minor ways. Makes you wonder what&#8217;s left for PHP 5.5, let alone 6, though?</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2012/05/09/whats-new-in-php-5-4/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Passing Values by Reference in PHP 5</title><link>http://www.larryullman.com/2012/04/25/passing-values-by-reference-in-php-5/</link> <comments>http://www.larryullman.com/2012/04/25/passing-values-by-reference-in-php-5/#comments</comments> <pubDate>Wed, 25 Apr 2012 11:28:33 +0000</pubDate> <dc:creator>Larry</dc:creator> <category><![CDATA[PHP]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=3189</guid> <description><![CDATA[Every other year or so, I go through the PHP manual. Often I do this in coordination with a book I&#8217;m about to write, like now, as I&#8217;m writing the . Generally, though, I&#8217;m a big advocate of re-reading manuals. It&#8217;s a great way to correct mistaken thinking you may have, and to learn new [...]]]></description> <content:encoded><![CDATA[<p>Every other year or so, I go through the <a
href="http://www.php.net/manual/">PHP manual</a>. Often I do this in coordination with a book I&#8217;m about to write, like now, as I&#8217;m writing the <a
href="http://www.larryullman.com/2012/04/09/php-5-advanced-visual-quickpro-guide-3rd-edition-table-of-contents/">third edition of my &#8220;PHP 5 Advanced&#8221; book</a>. Generally, though, I&#8217;m a big advocate of re-reading manuals. It&#8217;s a great way to correct mistaken thinking you may have, and to learn new and better approaches. For example, I just came across something that had previously slipped past me: the ability to change an <a
href="http://www.php.net/manual/en/language.types.array.php">array</a> within a foreach loop by passing values by reference.</p><p>In versions of PHP prior to 5, in order to change the values of array elements within a loop, you had to do this:</p><pre class="brush: php; title: ; notranslate">foreach ($array as $key =&gt; $value) {
    $array[$key] = &quot;some updated $value&quot;;
}</pre><p>Just changing the value of <strong>$value</strong> within that <strong>foreach</strong> loop had no impact on the actual array element, as the loop only received the value of each array element, not the actual element itself.</p><p>This doesn&#8217;t come up often—if I need to change the elements in an array, I&#8217;m likely to use <a
href="http://www.php.net/array_walk">array_walk()</a>, but it&#8217;s nice to know that in PHP 5 you can pass array values by reference in a <strong>foreach</strong> loop, so that changing the value within the loop actually changes the array:</p><pre class="brush: php; title: ; notranslate">foreach ($array as &amp;$value) {
    $value = &quot;some updated $value&quot;;
}</pre><p>As you can see there, prefacing <strong>$value</strong> by <strong>&amp;</strong> means that the variable is passed by reference, not by value, just as you&#8217;d have in a function parameter.</p><p>Again, perhaps this isn&#8217;t a life changing thing to learn (okay, it isn&#8217;t), but it&#8217;s interesting to know. As I continue to work my way through the PHP manual (again!), I&#8217;ll continue to share interesting little tidbits I&#8217;m finding, or discovering anew.</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2012/04/25/passing-values-by-reference-in-php-5/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Yii and Me (aka, the Yii Book)</title><link>http://www.larryullman.com/2012/04/23/yii-and-me-aka-the-yii-book/</link> <comments>http://www.larryullman.com/2012/04/23/yii-and-me-aka-the-yii-book/#comments</comments> <pubDate>Mon, 23 Apr 2012 11:18:49 +0000</pubDate> <dc:creator>Larry</dc:creator> <category><![CDATA[MySQL]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Web Development]]></category> <category><![CDATA[book]]></category> <category><![CDATA[yii]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=3187</guid> <description><![CDATA[Thanks largely to the success of my Learning the Yii Framework series, people are often asking me about my plans to write a book on Yii. Writing a book on Yii is something that I&#8217;ve been meaning to do for some time, but have been way too busy for the past couple of years to [...]]]></description> <content:encoded><![CDATA[<p>Thanks largely to the success of my <a
href="http://www.larryullman.com/series/learning-the-yii-framework/">Learning the Yii Framework</a> series, people are often asking me about my plans to write a book on <a
href="http://www.yiiframework.com">Yii</a>. Writing a book on Yii is something that I&#8217;ve been meaning to do for some time, but have been way too busy for the past couple of years to make it happen. Every so often I post something about the phantom Yii book, and so here&#8217;s another. This time, it&#8217;s pretty good news&#8230;</p><p>As for my schedule, I&#8217;m now writing the third edition of my &#8220;<a
href="http://www.larryullman.com/2012/04/09/php-5-advanced-visual-quickpro-guide-3rd-edition-table-of-contents/">PHP 5 Advanced: Visual QuickPro Guide</a>&#8221; book. That project will take the next couple of months, through June. I&#8217;m hoping it will be entirely done (rewrites and all) in early July. I think I&#8217;ll have a decent-sized Web project to do in the fall, but other than that, I have no deadlines and obligations for the latter half of 2012. Little things will no doubt come along, but this kind of free time is unusual for me. (And, strangely, isn&#8217;t frightening at the moment, although free time come January could be a problem!) So, reasonably speaking, I will be able to work on the Yii book full time as of August 2012. This should coincide nicely with the hopeful release of Yii 2.0 over the summer. Speaking of which&#8230;</p><p>I&#8217;ve been chatting with Qiang Xue, the creator of Yii, and he has graciously offered to act as the personal tech editor for the book. This is a great honor to me, and will be a wonderful asset in making sure the book is as technically accurate as possible. In return, I&#8217;m going to help with some of the official Yii documentation (it&#8217;s the least I can do). And the good news keeps rolling in, as <a
href="http://rmcreative.ru/">Alex Makarov</a>, author of the popular <a
href="http://yiicookbook.org/">Yii 1.1 Application Development Cookbook</a> (Packt Publishing), has generously offered his assistance, too. These are invaluable pieces that are coming together nicely here.</p><p>In terms of publishing, my current plan is&#8230;</p><ul><li>To self-publish an ebook only. I will release it in mobi, epub, and PDF formats, without any annoying Digital Rights Management (DRM).</li><li>Possibly no DRM.</li><li>Probably no DRM.</li><li>The price would be about $15 (USD).</li><li>People would be able to buy the book in advance, and get each chapter as I write it. Revised chapters would be free updates.</li><li>People would be able to buy just a single chapter and get revisions of that chapter as free updates.</li></ul><p>I&#8217;m assuming that I&#8217;ll create a separate Web site for the book, as I&#8217;m also planning on making some of the book&#8217;s content freely available in HTML format. This does mean that along with writing the book, I&#8217;ll have to create the Web site and the above functionality, but such are the costs of doing things yourself. And I happen to know of a framework that makes Web development a lot faster&#8230;</p><p>I&#8217;ll continue posting updates here and on <a
href="http://www.twitter.com">Twitter</a> (by the way, I&#8217;m on Twitter <a
href="https://twitter.com/#!/LarryUllman">@LarryUllman</a>) as I have them. Yii postings may be sporadic for the next couple of months as I focus on the PHP Advanced book, but rest assured the Yii book is happening.</p><p>All thoughts, feedback, input, and offers of money are most welcome!</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2012/04/23/yii-and-me-aka-the-yii-book/feed/</wfw:commentRss> <slash:comments>40</slash:comments> </item> <item><title>Properly Salting Passwords, The Case Against Pepper</title><link>http://www.larryullman.com/2012/04/20/properly-salting-passwords-the-case-against-pepper/</link> <comments>http://www.larryullman.com/2012/04/20/properly-salting-passwords-the-case-against-pepper/#comments</comments> <pubDate>Fri, 20 Apr 2012 11:36:26 +0000</pubDate> <dc:creator>Larry</dc:creator> <category><![CDATA[MySQL]]></category> <category><![CDATA[PHP]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=3185</guid> <description><![CDATA[Anthony Ferrara, creator of the PHP PasswordLib library, just recently posted a discussion of using salts and pepper to improve the security of a stored password. Mostly, the article is a discussion of why a pepper is unnecessary (and if you don&#8217;t know what a &#8220;pepper&#8221; is, just read the article), but the posting also does [...]]]></description> <content:encoded><![CDATA[<p>Anthony Ferrara, creator of the PHP <a
href="https://github.com/ircmaxell/PHP-PasswordLib">PasswordLib</a> library, just recently <a
href="http://blog.ircmaxell.com/2012/04/properly-salting-passwords-case-against.html">posted a discussion of using salts and pepper</a> to improve the security of a stored password. Mostly, the article is a discussion of why a pepper is unnecessary (and if you don&#8217;t know what a &#8220;pepper&#8221; is, just read the article), but the posting also does a good job of explaining the purpose of a salt, and why the salt does not need to be a secret. The posting is relatively short, and is something I think everyone can benefit from reading.</p><p>The posting ends with the most important security fact:</p><blockquote><p>Remember, the most dangerous kind of security is a false sense of it. Thinking you&#8217;ve made your application more secure, when in fact you&#8217;ve weakened it, is the worst thing you could possibly do.</p></blockquote> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2012/04/20/properly-salting-passwords-the-case-against-pepper/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>&#8220;PHP 5 Advanced: Visual QuickPro Guide (3rd Edition&#8221; Table of Contents</title><link>http://www.larryullman.com/2012/04/09/php-5-advanced-visual-quickpro-guide-3rd-edition-table-of-contents/</link> <comments>http://www.larryullman.com/2012/04/09/php-5-advanced-visual-quickpro-guide-3rd-edition-table-of-contents/#comments</comments> <pubDate>Mon, 09 Apr 2012 11:01:26 +0000</pubDate> <dc:creator>Larry</dc:creator> <category><![CDATA[MySQL]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Web Development]]></category> <category><![CDATA[oop]]></category> <category><![CDATA[phpvqp3]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=3168</guid> <description><![CDATA[I&#8217;m just about to begin writing the third edition of my &#8220;&#8221;. This new edition is tentatively titled &#8220;Advanced PHP and Object-Oriented Programming: Visual QuickPro Guide&#8221;, which better reflects the book&#8217;s focus. The book is written for intermediate PHP and Web developers, and covers a range of topics to further extend what you know into more [...]]]></description> <content:encoded><![CDATA[<p>I&#8217;m just about to begin writing the third edition of my &#8220;<a
href="http://www.larryullman.com/books/php-5-advanced-visual-quickpro-guide-2nd-edition/">PHP 5 Advanced: Visual QuickPro Guide</a>&#8220;. This new edition is tentatively titled &#8220;Advanced PHP and Object-Oriented Programming: Visual QuickPro Guide&#8221;, which better reflects the book&#8217;s focus. The book is written for intermediate PHP and Web developers, and covers a range of topics to further extend what you know into more real-world, complex situations.<span
id="more-3168"></span></p><p>The previous edition had 14 chapters, plus two that were made available as free PDFs (one on image generation, the other on PDF generation). The current plan for this edition is to cut four chapters, add four entirely new chapters, and the add and remove some chapter sections here and there. The book will also have a &#8220;Review and Pursue&#8221; section at the end of each chapter, with review questions and pursue prompts.</p><p>My goals for this edition of the book were (in no particular order):</p><ul><li>Emphasize and expand the OOP sections</li><li>Add more content geared towards creating larger, more elaborate, professional Web applications</li><li>Add new content based upon changes in technologies since the last edition (specifically changes in PHP from version 5.2 to 5.4)</li><li>Update outdated content (including replacing old approaches with entirely new ones)</li><li>Removing no longer critical content</li><li>Removing content now discussed in other books of mine</li></ul><p>For example, new PHP features that will be covered include <a
href="http://php.net/manual/en/language.oop5.typehinting.php">type hinting</a>, the <a
href="http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.nowdoc">Nowdoc</a> syntax, and <a
href="http://www.php.net/manual/en/language.oop5.traits.php">traits</a>. New Web application information include discussions of Apache&#8217;s mod_rewrite and <a
href="http://www.phpdoc.org/">phpDocumentor</a>, and a chapter on debugging tools, unit testing, and improving performance. The expanded OOP material includes a chapter on design patterns and a new chapter that creates a whole example using OOP.</p><p>With all that in mind, the initial Table of Contents is posted below. New content is in <span
style="color: #339966;">green</span>. Chapters I&#8217;ve cut (not reflected below) include one on security techniques (now well covered by my other books), another on e-commerce (I&#8217;ve since written a<a
href="http://www.larryullman.com/books/effortless-e-commerce-with-php-and-mysql/">whole book</a> on that), the PEAR chapter (replaced by one on the <a
href="http://framework.zend.com">Zend Framework</a>), and the Ajax chapter (well covered in many of my other books).</p><p>If you have any thoughts or suggestions, I&#8217;d love to hear them. Thanks!</p><ul><li>Chapter 1: Advanced PHP Techniques<ul><li>Multidimensional Arrays</li><li>Advanced Function Definitions</li><li><span
style="color: #339966;">Type Hinting</span></li><li><span
style="color: #339966;">Anonymous Functions</span></li><li>The Heredoc and <span
style="color: #339966;">Nowdoc</span> Syntax</li><li>Using printf() and sprintf()</li></ul></li><li>Chapter 2: Developing Web Applications<ul><li>Modularizing a Web Site</li><li><span
style="color: #339966;">Improved SEO with mod_rewrite</span></li><li>Affecting the Browser Cache</li><li><span
style="color: #339966;">Better Documentation with phpDocumentor</span></li></ul></li><li>Chapter 3: Advanced Database Concepts<ul><li>Storing Sessions in a Database</li><li>Working with U.S. Zip Codes</li><li>Creating Stored Functions</li><li>Displaying Results Horizontally</li><li><span
style="color: #339966;">Storing Binary Data</span></li><li><span
style="color: #339966;">Using PDO</span></li></ul></li><li><span
style="color: #339966;">Chapter 4: Debugging, Testing, and Performance</span><ul><li><span
style="color: #339966;">Debugging Tools</span></li><li><span
style="color: #339966;">Unit Testing</span></li><li><span
style="color: #339966;">Profiling Scripts</span></li><li><span
style="color: #339966;">Improving Performance</span></li><li><span
style="color: #339966;">Implementing Server Caches</span></li></ul></li><li>Chapter 5: Basic Object-Oriented Programming<ul><li>OOP Theory</li><li>Defining a Class</li><li>Creating an Object</li><li>The $this Attribute</li><li>Creating Constructors</li><li>Creating Destructors</li><li>Autoloading Classes</li></ul></li><li>Chapter 6: Advanced OOP<ul><li>Advanced Theories</li><li>Inheriting Classes</li><li>Inheriting Constructors and Destructors</li><li>Overriding Methods</li><li>Access Control</li><li>Using the Scope Resolution Operator</li><li>Creating Static Members</li><li>Abstract Classes and Methods</li><li><span
style="color: #339966;">Creating Namespaces</span></li><li><span
style="color: #339966;">Using Traits</span></li></ul></li><li><span
style="color: #339966;">Chapter 7: Design Patterns</span><ul><li><span
style="color: #339966;">What are Design Patterns?</span></li><li><span
style="color: #339966;">[[Discussion of Specific Patterns TBD]]</span></li></ul></li><li>Chapter 8: Real-World OOP<ul><li>Catching Exceptions</li><li>Extending the Exception Class</li><li><span
style="color: #339966;">Implementing MVC</span></li><li><span
style="color: #339966;">Using the Standard PHP Library</span></li><li><span
style="color: #339966;">OOP-based E-commerce</span></li></ul></li><li><span
style="color: #339966;">Chapter 9: Example&#8211;CMS with OOP</span></li><li>Chapter 10: Networking with PHP<ul><li>Accessing Other Web Sites</li><li>Working with Sockets</li><li>Performing IP Geolocation</li><li>Using cURL</li><li><span
style="color: #339966;">Creating Web Services</span></li></ul></li><li>Chapter 11: PHP and the Server<ul><li>Compressing Files</li><li>Establishing a cron</li><li>Scheduling Tasks on Windows</li><li><span
style="color: #339966;">Using PHP’s Built-In Server</span></li></ul></li><li>Chapter 12: PHP’s Command-Line Interface<ul><li>Testing Your Installation</li><li>Executing Bits of Code</li><li>Creating a Command-Line Script</li><li>Running a Command-Line Script</li><li>Working with Command-Line Arguments</li><li>Taking Input</li></ul></li><li>Chapter 13: XML and PHP<ul><li>What Is XML?</li><li>XML Syntax</li><li>Attributes, Empty Elements, and Entities</li><li>Document Type Definitions</li><li>Parsing XML</li><li>Creating an RSS Feed</li><li><span
style="color: #339966;">XML Error Handling</span></li></ul></li><li><span
style="color: #339966;">Chapter 14: Using the Zend Framework</span><ul><li><span
style="color: #339966;">Installation</span></li><li><span
style="color: #339966;">Creating and Validating Forms</span></li><li><span
style="color: #339966;">Adding Captcha</span></li><li><span
style="color: #339966;">Implementing Authentication</span></li><li><span
style="color: #339966;">Using Zend_Mail</span></li></ul></li></ul> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2012/04/09/php-5-advanced-visual-quickpro-guide-3rd-edition-table-of-contents/feed/</wfw:commentRss> <slash:comments>28</slash:comments> </item> <item><title>What is Larry Thinking? #53 =&gt; Writing and Working</title><link>http://www.larryullman.com/2012/04/02/what-is-larry-thinking-53-writing-and-working/</link> <comments>http://www.larryullman.com/2012/04/02/what-is-larry-thinking-53-writing-and-working/#comments</comments> <pubDate>Mon, 02 Apr 2012 11:02:50 +0000</pubDate> <dc:creator>Larry</dc:creator> <category><![CDATA[JavaScript]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Web Development]]></category> <category><![CDATA[article]]></category> <category><![CDATA[book]]></category> <category><![CDATA[jsdd]]></category> <category><![CDATA[mamp]]></category> <category><![CDATA[newsletter]]></category> <category><![CDATA[phpvqp3]]></category> <category><![CDATA[twitter]]></category> <category><![CDATA[writing]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=3167</guid> <description><![CDATA[In this edition… On the Web =&#62; Follow Me on Twitter! Redux On the Web =&#62; Three JavaScript Articles I wrote On the Blog =&#62; MAMP without MAMP Q&#38;A =&#62; Can I Make a Living as a Writer? What is Larry Thinking =&#62; Competing for Work Larry Ullman&#8217;s Book News =&#62; “Modern JavaScript: Develop and [...]]]></description> <content:encoded><![CDATA[<p>In this edition…</p><ul><li><a
href="http://www.larryullman.com/2012/04/02/what-is-larry-thinking-53-writing-and-working/#web1">On the Web =&gt; Follow Me on Twitter! Redux</a></li><li><a
href="http://www.larryullman.com/2012/04/02/what-is-larry-thinking-53-writing-and-working/#web2">On the Web =&gt; Three JavaScript Articles I wrote</a></li><li><a
href="http://www.larryullman.com/2012/04/02/what-is-larry-thinking-53-writing-and-working/#blog">On the Blog =&gt; MAMP without MAMP</a></li><li><a
href="http://www.larryullman.com/2012/04/02/what-is-larry-thinking-53-writing-and-working/#qa">Q&amp;A =&gt; Can I Make a Living as a Writer?</a></li><li><a
href="http://www.larryullman.com/2012/04/02/what-is-larry-thinking-53-writing-and-working/#thinking">What is Larry Thinking =&gt; Competing for Work</a></li><li><a
href="http://www.larryullman.com/2012/04/02/what-is-larry-thinking-53-writing-and-working/#news">Larry Ullman&#8217;s Book News =&gt; “Modern JavaScript: Develop and Design” and “PHP 5 Advanced: Visual QuickPro Guide” (3rd Edition)</a></li></ul><p><span
id="more-3167"></span></p><h2 id="web1">On the Web =&gt; Follow Me on Twitter! Redux</h2><p>To reiterate something I said in the <a
href="http://www.larryullman.com/2012/03/12/what-is-larry-thinking-52-twitter/#web1">previous newsletter</a>, I am now officially on <a
href="http://twitter.com">Twitter</a>. You can follow me using <a
href="https://twitter.com/#!/LarryUllman">@LarryUllman</a>. In the three-ish weeks since I started using it, I’ve only sent out maybe a dozen group tweets (not counting the ones directly to specific people), but at least there have been no “I am now having a sandwich.”-type tweets. Not by me anyway.</p><p>So far, a nice ego bump when it comes to Twitter is seeing people mention me (yes, yes, I am an idiot regarding Twitter; I didn’t know about that aspect at all). The annoying and stunning thing is that I’m occasionally getting hit up for technical support. It really quite amazes me that one would think I could provide free, instant tech support, and within 140 characters! Of course, I’m happy to provide free tech support, which is why I created my <a
href="http://www.larryullman.com/forums/">support forums</a>, but I just don&#8217;t think Twitter is the best medium for it.</p><h2 id="web2">On the Web =&gt; Three JavaScript Articles I Wrote</h2><p>In support of my “<a
href="http://www.larryullman.com/books/modern-javascript-develop-and-design/">Modern JavaScript: Develop and Design</a>” book, I wrote three articles to be published online by <a
href="http://peachpit.com">Peachpit Press</a>. All three are now available:</p><ul><li><a
href="http://www.peachpit.com/articles/article.aspx?p=1843879">The Five Biggest JavaScript Misconceptions</a></li><li><a
href="http://www.peachpit.com/articles/article.aspx?p=1847299">The 10 Best JavaScript Development and Design Habits</a></li><li><a
href="http://www.peachpit.com/articles/article.aspx?p=1851233">5 Ways to Improve Your Ajax Performance</a></li></ul><p>The articles don’t require that you have the book. And, of course, they’re free, so check them out when you get the chance. Thanks!</p><h2 id="blog">On the Blog =&gt; MAMP without MAMP</h2><p>For a couple of years now, I’ve used, and advocated using, the <a
href="http://mamp.info/en/index.html">MAMP application</a> as the easiest way to run a Web server on a Mac. I’ve started to change my thinking about that, as discussed in a <a
href="http://www.larryullman.com/2012/02/24/mamp-without-mamp/">recent blog post</a>.</p><h2 id="qa">Q&amp;A =&gt; Can I Make a Living as a Writer?</h2><p>“Can I make a living as a writer?” is one of the more common questions I get, and one I never mind answering. Both Helmut and Scott recently asked me about the logistics of being a writer, so it seems like a good time to rehash the topic.</p><p>In terms of hard numbers, how lucrative writing a book is all depends upon how well the book sells. As a reasonable basis number, assume you can get $10,000 (USD) to write a book, which is the <strong>advance</strong>. Some publishers will pay more, some will pay less. It also depends upon who you are and what the book is. But $10,000 is fair. And that money is yours to keep, no matter what happens (assuming you complete the book to the publisher’s satisfaction). If you can write two books per year, that’s $20,000. If you can write three, that’s $30,000. In the past, there have been years in which I wrote three books in a single year, and it’s really hard to do, not just because you have to have three good ideas and enough expertise on three subjects, but because writing a single book is quite draining.</p><p>Added to that, write an article a month, just to get some extra income and to help promote the books. Let’s say you’re paid $500 each for those. Most of the articles I write pay less than that, but the occasional article pays dramatically more. One article per month at $500 per is another $6,000. Keep in mind that, as with the books, you have to have the ideas, have the knowledge, and then put forth the effort to get someone to buy the article. That’s all time consuming, but the actual act of writing an article isn’t that hard. It’s really just a professional blog posting.</p><p>So now, with a fair amount of work and effort, you’ve managed to bring in $26,000. At least in the United States, from this income you have to pay all the taxes and such, so the actual net may be more like $20,000. Does that constitute a living for you? I’m sure some of you would be losing a lot of money to take that deal and others would be fine with it. But I think that’s what you could reasonably expect as a bottom line if you’re a good writer and put in the necessary work. The other end of the spectrum depends upon how well your books sell.</p><p>A good seller in computer books is around 10,000 copies. Different titles have different expectations, but my understanding is that if you sell 10,000 copies, you’ve done well. This number varies greatly, but a decent expectation is that you, the writer, will make $2 per copy sold. If you sell 10,000 copies, that’s $20,000 on that one book. Minus the $10,000 advance, there’s another $10,000 for you. But that $10k will be spread out over some years. In my last statement, I received $11.19 in royalties for my first book published over a decade ago (with three new editions since then). The best part is that you’ve done no extra direct work for that money above and beyond the advance, but you can’t count on it, and you’ll likely have to do a lot of marketing work to help make that happen. Still, by earning advances for writing new titles and hopefully getting royalties on existing titles, you might be able to bring your total yearly writing income up to $30,000 to $40,000. Eventually.</p><p>In terms of harder numbers, you could probably consider me to be fairly successful as a computer writer (I mean in terms of actual sales, not necessarily the quality of the books, which is a different criteria). My first book came out almost exactly 11 years ago and I’ve now written 22 books, including revisions. I’ve sold approximately 325,000 copies in sum, for approximately $577,000. That may seem like a grand sum of money (and, to be clear, I’m happy to have earned it), but that’s over 11 years, which is about $52,000 per year during that time. Again, many of you would probably be thrilled with that number (and I’m okay with it), but remember that taxes have to come out of that and I get no benefits whatsoever. In the United States, benefits are normally estimated to be equivalent to the salary itself (i.e., if you’re being paid $40,000 per year, the company is probably spending another $40,000 for your retirement, medical, and other benefits). So one could look at that $52,000 per year as really being more like $26,000 per year, gross, plus benefits. And, again, I do fairly well for a writer. I’ll add that I’m just starting to make money through my blog, but right now that’s a few hundred dollars per year. Perhaps one day I’ll get that to a few hundred dollars a month, but I don’t envision this avenue to be a significant form of income.</p><p>There are some very hard numbers for what it might mean to make a living as a writer. For some people, the idea of making, say, $30,000 to $40,000 (USD) per year as a writer would be great. And there are intangible benefits. I work for myself, at home. I don’t commute. I don’t do many meetings. I learn and write about things I’m interested in. And there’s a lot of flexibility in my schedule which helps out tremendously considering the personal demands that I have. For other people, the idea of making that amount of money, with no guarantees, regular paychecks, or benefits would send them screaming to the nearest stable job.</p><p>I should add that writing does allow you to make good money doing related things. For example, I also do Web development and other programming, consulting, training, and speaking. My writing does act as a marketing agent for these avenues, meaning it’s easier for me to get work and I can charge a premium for those services.</p><p>All things considered, the general advice I have is: while it is possible to make money writing books (and/or articles), I wouldn’t recommend anyone to go into writing for that purpose. The odds of making money, let alone sufficient money, are slim. There’s a lot of competition, the publishing industry is definitely down, and the best payoffs are definitely in the long term. Also, in case I didn’t make this clear, writing a book is really quite hard. If you’re looking to go into business for yourself, there are certainly more stable, lucrative routes. It’d be much better to pursue writing only because you like to write and share what you’ve learned. And I’m not just saying that to cut down on the competition!</p><h2 id="thinking">What is Larry Thinking? =&gt; Competing for Work</h2><p>Some time back, William asked for my thoughts on how to compete for work, considering foreign competition and a tough economy. Two weeks ago, I was on the other side of the equation for the first time, as I ran a <a
href="http://99designs.com/">99designs</a> contest to have a new logo and business card created for me. I’ve been sketching out a blog posting tentatively titled “How Not To Get Work” about that experience, but I’ll toss out some thoughts here, too. (As an aside, the contest went great and I’ll post the details about it on my site soon. I got a great logo and business card, which are currently being used as the basis for a revamping of my Web site.)</p><p>This problem—a bad economy and competing with foreign developers who can offer bargain prices—is not new, although it may be new to those who haven’t been freelancing for that long. Just after I started in this line of work, the “dot com” bubble burst. At the time I was getting work through online freelancing sites like elance and guru, sometimes losing out to people that drastically undercut my price. For example, there was a big banking job that I lost out to a company in India that underbid me. That project would have been huge for me—around $22,000, I think, when I didn’t make that in a year, but on the other hand, I wasn’t really prepared or qualified to do that job at that time, so it was probably for the best. In any case, how does one compete?</p><p>In my opinion, you have to first accept two facts:</p><ul><li>Just because a competitor is in X country and is willing to do the job for much cheaper, it doesn’t mean that developer won’t do as good as a job as you.</li><li>For the person buying the services, price is logical, significant factor.</li></ul><p>I mention these two ideas because you can’t succeed if you get bogged down in excuses. The cost of living in X country may be a fraction of what it is in your country, which makes it possible for developers in X to offer what seem like cut-rate prices. But that doesn’t mean that developer can’t do the job. So the arguments for hiring you instead of those cheaper developers can’t be based upon that assumption. Second, while it is often true that you get what you pay for, it’s also true that business fail when they spend more than they have to. Accepting a cheaper bid doesn’t mean the client is cheap, it means the client is making a sound business decision (hopefully). So what can you do?</p><p>There’s only one thing you can control when competing for work: you. <em>Focus on what you can do</em>, not what’s wrong with the other developers or the client’s thought process. Towards that end:</p><ul><li><strong>Above all, be professional in every way.</strong> Every single thing you do should demonstrate professionalism on the highest level. This includes how well you handle not getting a job. You never know: your ability to handle failure professionally may just be the reason that the client comes back to you for a future project.</li><li><strong>Communicate well, both in quality and in timeliness.</strong> Be prompt, responsive, and literate.</li><li><strong>Offer the best, most appropriate price you can.</strong> Be aware of what other prices the client may see, but base your price on what you think is appropriate for the job. Do factor in how much you need the job, how much you want the job, and so forth, but try to strike a balance between asking enough that you won’t be annoyed if you get the job while still being as affordable as you can be.</li><li><strong>Stress and demonstrate your less obvious strengths.</strong> While money is a mitigating factor for the client, it’s not the only one. If you can’t compete on a pure cost basis, work on other angles. For example, a developer in X country might be cheaper but may also be 12 hours away; a simple Q&amp;A could take a whole day in that case. Or, if you will be available via IM or Skype, that’s a bonus.</li><li><strong>Do the work in advance.</strong><strong> The absolute best way to demonstrate that you’re capable of doing a job, and on time, is to do the job ahead of time. My second client ever, for whom I’m still doing work, was one I got when I did a bit of JavaScript for an elance project he was hiring for. During the bidding process, as part of my bid, I linked to a page where the client could see the finished work. It was <em>easy</em> for that client to hire me at that point. Yes, this means I did work for free, and because it was JavaScript, anyone could have stolen my code, but I had the free time and needed the money, so I went out on a limb. I did that many times when I first started and my success rate was high because of it.</strong></li></ul><p>William had also specifically asked about how to convince small business owners to start or revise a Web site. I will say that I’m pretty good at convincing someone to hire me to do a project, but I have no skill when it comes to convincing someone that a project is necessary. In short, I wouldn’t have the vaguest idea how to proceed here. I would <strong>guess</strong> that it’d be more effective if you tie some of your payment into the site’s success (i.e., establish quantifiable goals that trigger payments or bonuses). That would clearly convey that you believe in the project, but it is risky.</p><p>As a final piece of advice, I’ll add that getting the job (and the money) isn’t the only benefit to be gained from trying to get work. There’s a lot to be said for the experience gained by being involved in the process. Certainly that’s a “silver lining” perspective, but if you can handle the failure to win the job, you can learn a ton from just participating. With open eyes, you can see what clients are looking for and what winning developers are doing right. In thinking about my 99designs contest, which had approximately 100 designers, about a third of the designers really didn’t have the skill set to compete. But those designers did get to see what a winning designer does, how a client behaves, and how to manage the interaction. In my opinion, that’s all quite valuable experience.</p><h2 id="news">Larry Ullman’s Book News =&gt; “Modern JavaScript: Develop and Design” and “PHP 5 Advanced: Visual QuickPro Guide” (3rd Edition)</h2><p>The <a
href="http://www.larryullman.com/books/modern-javascript-develop-and-design/">JavaScript book</a> is done and available at a store near you. The early reviews seem to be good, for which I’m quite grateful. I already gave away half of the copies I had to people that replied to previous newsletters, so right now I’m not planning on doing another dedicated “Modern JavaScript: Develop and Design” giveaway. I <strong>might</strong> have a couple more copies to give away later in the year. We shall see.</p><p>Next week I begin writing the third edition of my “PHP 5 Advanced: Visual QuickPro Guide”, which will come out this summer. I’m finished the new table of contents and I’ll put that online soon. The current plan is to cut four chapters that contain material since covered in my other books. I’m adding four new chapters, too:</p><ul><li>Debugging, Testing, and Performance</li><li>Design Patterns</li><li>A chapter that creates a complete example using OOP</li><li>Using the Zend Framework</li></ul><p>There are also some minor cuts and additions. The general thrust in this rewrite is to expand the book largely in the areas of Object-Oriented Programming and advanced Web development. The OOP additions include design patterns, implementing MVC, using the <a
href="http://www.php.net/spl">Standard PHP Library</a>, and an example application writing in OOP. For the latter, Im specifically thinking about things like using <a
href="http://www.phpdoc.org/">phpDocumentor</a>, <a
href="http://www.php.net/pdo">PDO</a>, caching, and unit testing.</p><p>If you have any thoughts or suggestions, I would love to hear them. Thanks!</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2012/04/02/what-is-larry-thinking-53-writing-and-working/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Under the Hood of Yii&#8217;s Component Architecture</title><link>http://www.larryullman.com/2012/03/16/under-the-hood-of-yiis-component-architecture/</link> <comments>http://www.larryullman.com/2012/03/16/under-the-hood-of-yiis-component-architecture/#comments</comments> <pubDate>Fri, 16 Mar 2012 14:13:51 +0000</pubDate> <dc:creator>Larry</dc:creator> <category><![CDATA[MySQL]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Web Development]]></category> <category><![CDATA[framework]]></category> <category><![CDATA[mvc]]></category> <category><![CDATA[yii]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=3055</guid> <description><![CDATA[If you haven&#8217;t yet seen it, Steven O&#8217;Brien wrote an in-depth series of articles on the Yii framework&#8217;s component architecture, posted at phpmaster. In the series, O&#8217;Brien looks at the CComponent base class in detail. Every class in Yii is an extension of CComponent, so understanding what it brings to the table can be quite [...]]]></description> <content:encoded><![CDATA[<p>If you haven&#8217;t yet seen it, <a
href="http://steve-obrien.com/">Steven O&#8217;Brien</a> wrote an in-depth series of articles on the Yii framework&#8217;s component architecture, posted at <a
href="http://phpmaster.com">phpmaster</a>. In the series, O&#8217;Brien looks at the <a
href="http://www.yiiframework.com/doc/api/1.1/CComponent">CComponent</a> base class in detail. Every class in Yii is an extension of <strong>CComponent</strong>, so understanding what it brings to the table can be quite useful to the Yii developer. <a
href="http://phpmaster.com/yii-under-the-hood-1/">Part 1</a> looks at the classes key properties and methods. <a
href="http://phpmaster.com/yii-under-the-hood-2/">Part 2</a> discusses events. And <a
href="http://phpmaster.com/under-the-hood-of-yii’s-component-architecture-part-3/">part 3</a> explains the behaviors. If you&#8217;re using Yii, it&#8217;s worth reading these to better understand what&#8217;s going on at the fundamental level.</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2012/03/16/under-the-hood-of-yiis-component-architecture/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Using PayPal&#8217;s WebSite Payments Pro with &#8220;Effortless E-Commerce with PHP and MySQL&#8221;</title><link>http://www.larryullman.com/2012/03/07/using-paypals-website-payments-pro-with-effortless-e-commerce-with-php-and-mysql/</link> <comments>http://www.larryullman.com/2012/03/07/using-paypals-website-payments-pro-with-effortless-e-commerce-with-php-and-mysql/#comments</comments> <pubDate>Wed, 07 Mar 2012 15:25:15 +0000</pubDate> <dc:creator>Larry</dc:creator> <category><![CDATA[MySQL]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Web Development]]></category> <category><![CDATA[e-commerce]]></category> <category><![CDATA[ecom]]></category> <category><![CDATA[paypal]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=3132</guid> <description><![CDATA[In Part 3 of my &#8220;&#8221; book, I use Authorize.net to process payments for a site that sells physical goods. Authorize.net accepts credit cards and can be directly integrated into your site, so that the customer never leaves (unlike, for example, PayPal&#8217;s Website Payments Standard, used in Part 2 of the book, which goes through [...]]]></description> <content:encoded><![CDATA[<p>In Part 3 of my &#8220;<a
href="http://www.larryullman.com/books/effortless-e-commerce-with-php-and-mysql/">Effortless E-Commerce with PHP and MySQL</a>&#8221; book, I use <a
href="http://www.authorize.net/">Authorize.net</a> to process payments for a site that sells physical goods. Authorize.net accepts credit cards and can be directly integrated into your site, so that the customer never leaves (unlike, for example, PayPal&#8217;s Website Payments Standard, used in Part 2 of the book, which goes through PayPal&#8217;s site). The code in the book was written in a very modular style, with the intent that you can use the components you need, and swap others in and out. A reader specifically wanted to know how you would use PayPal&#8217;s Website Payments Pro instead of Authorize.net, and that&#8217;s what I&#8217;ll explain here.<span
id="more-3132"></span></p><p>PayPal&#8217;s Website Payments Pro provides two APIs for processing payments: <em>Direct Payment</em> and <em>Express Checkout</em>. Both allow you to accept debit and credit cards (the specific cards will differ slightly from one region to the next), while Express Checkout also allows users to pay with their PayPal account. In both cases, the customer never leaves your site, unlike when using PayPal&#8217;s Website Payments Standard. PayPal does require you to use both APIs in order to use Website Payments Pro. To keep this post from getting too long, I&#8217;ll only address the Direct Payment, which most easily correlates to the Authorize.net code in the book. If you need help with the Express Checkout aspect, let me know.</p><p>To understand how to use Website Payments Pro instead of Authorize.net for the second example, let&#8217;s first look at how Authorize.net is used. The customer begins the checkout process on <strong>checkout.php</strong>. This script takes and validates the user&#8217;s shipping information. Upon successful validation, the user is redirected to <strong>billing.php</strong>, which takes and validates the billing information, including the credit card. Upon successful validation, the payment is processed by including two scripts: <strong>gateway_setup.php</strong> and <strong>gateway_process.php</strong>. For extra security, these two files are stored in a private folder outside of the Web root directory.</p><p>Within<strong> gateway_setup.php</strong>, a bunch of parameters are set within an array named <strong>$data</strong>:</p><pre class="brush: php; title: ; notranslate">&lt;?php
$data = array();
$data['x_type'] = 'AUTH_ONLY';
$data['x_card_num'] = $cc_number;
$data['x_exp_date'] = $cc_exp;
// etc. </pre><p>Then the <strong>gateway_process.php</strong> script adds some more details to the array:</p><pre class="brush: php; title: ; notranslate">// Your account info:
$data['x_login'] = '75sqQ96qHEP8';
$data['x_tran_key'] = '7r83Sb4HUd58Tz5p';
// etc. </pre><p>Finally, <strong>gateway_process.php</strong> converts that data into a useable format for the <a
href="http://curl.haxx.se/">cURL</a> request, performs the cURL request, and reads the response into the <strong>$response</strong> variable. Finally, this variable is converted into an array:</p><pre class="brush: php; title: ; notranslate">$response_array = explode($data[&quot;x_delim_char&quot;],$response);</pre><p>That&#8217;s the end of the <strong>gateway_process.php</strong> script. The script that invokes it—<strong>billing.php—</strong>will then use <strong>$response_array</strong> to take the next logical steps.</p><p>In order to switch the payment gateway in use, you must replace the code in <strong>gateway_setup.php</strong> and <strong>gateway_process.php</strong>. This is much easier than you might think. For PayPal&#8217;s Website Payments Pro, you&#8217;ll need to change the code in those two files so that instead of creating, for example, <strong>$data['x_card_num']</strong>, it creates <strong>$data['ACCT']</strong>. The proper values and their meanings can be found in the <a
href="https://www.x.com/developers/paypal/documentation-tools/api/dodirectpayment-api-operation-nvp">PayPal documentation</a>.  This means that <strong>gateway_setup.php</strong> would contain:</p><pre class="brush: php; title: ; notranslate">&lt;?php
$data['PAYMENTACTION'] = 'Authorization';

// Billing info:
$data['ACCT'] = $cc_number;
$data['EXPDATE'] = $cc_exp;
$data['CREDITCARDTYPE'] = $cc_type;
$data['CVV2'] = $cc_cvv;
$data['FIRSTNAME'] = $cc_first_name;
$data['LASTNAME'] = $cc_last_name;
$data['STREET'] = $cc_address;
$data['STATE'] = $cc_state;
$data['CITY'] = $cc_city;
$data['ZIP'] = $cc_zip;
$data['COUNTRY'] = 'US'; // Or other, if accepting international orders.
$data['IPADDRESS'] = $_SERVER['REMOTE_ADDR'];</pre><p>As in the book, these orders are being authorized first and captured later. The actual transfer of funds takes place in a second step, when the order ships. For simplicity sake, you could change the <strong>PAYMENTACTION</strong> to <em>Sale</em>, assuming that would be appropriate (and legal) in your situation. PayPal also wants you to pass along the customer&#8217;s IP address, for fraud prevention purposes. And you&#8217;ll need to get the credit card type from the user, which isn&#8217;t requested in the book&#8217;s original code.</p><p>Next, <strong>gateway_process.php</strong> needs your own information:</p><pre class="brush: php; title: ; notranslate">// Your account info:
$data['SIGNATURE'] = 'your API signature';
$data['USER'] = 'your API username';
$data['PWD'] = 'your API password';</pre><p>This information will be determined when you sign up for Website Payments Pro with your PayPal business account.<br
/> Next, there&#8217;s the payment gateway stuff:</p><pre class="brush: php; title: ; notranslate">// PayPal Website Payments Pro Stuff:
$data['VERSION'] = '85.0';

// Transaction stuff:
$data['METHOD'] = 'DoDirectPayment';</pre><p>And then there&#8217;s the order information:</p><pre class="brush: php; title: ; notranslate">// Order info:
$data['AMT'] = $order_total;
$data['CURRENCYCODE'] = 'USD';
$data['INVNUM'] = $order_id;
$data['CUSTOM'] = $customer_id;</pre><p>The <strong>CUSTOM</strong> option lets you send your own data along, in this case the customer ID (although the customer ID could also be retrieved later via the transaction ID).</p><p>(Note: Dividing the data into these two files may seem odd, but it&#8217;s done so that the administrative side can easily use the same <strong>gateway_process.php</strong> script, after running a <strong>gateway_setup_admin.php</strong> script. If you need help with the admin process, to capture a prior authorization, let me know.)</p><p>Also, the <strong>GATEWAY_API_URL</strong> constant in <strong>gateway_process.php</strong> needs to be changed to PayPal&#8217;s proper URL: <em>https://api-3t.sandbox.paypal.com/nvp</em> for testing, <em>https://api-3t.paypal.com/nvp</em> for live purposes.</p><p>After identifying all the values, the <strong>gateway_process.php</strong> script converts that data into a string of URL-encoded name-value pairs. That does not need to be changed, nor does the cURL request made at the end of that script.</p><p>In response to the request, PayPal will return a string which contains more name-value pairs: <em>TIMESTAMP=X&amp;ACK=Success&amp;VERSION=85&amp;&#8230;</em> This must be broken into an array:</p><pre class="brush: php; title: ; notranslate">$a = explode('&amp;', $response);
$response_array = array();
foreach ($a as $item) {
 list($key, $value) = explode('=', $item);
 $response_array[$key] = $value;
}</pre><p>This code is a bit different and more complex than the Authorize.net code, as Authorize.net only returns a string broken up by the pipe character (|). But at this point, &lt;strong&gt;$response_array&lt;/strong&gt; is usable. Unfortunately, &lt;strong&gt;billing.php&lt;/strong&gt; will need to be modified, because that script assumes a numerically indexed array. First, you&#8217;ll need to change the call to the stored procedure:</p><pre class="brush: php; title: ; notranslate">$r = mysqli_query($dbc, &quot;CALL add_transaction($order_id, '{$data['PAYMENTACTION']}', $response_array['AMT'], $response_array['ACK'], '$response_array['PAYMENTADVICECODE']', $response_array['TRANSACTIONID'], '$response')&quot;);</pre><p>After that code, different reactions occur based upon the success of the transaction. To check that, use <strong>$response_array['ACK']</strong>, which should have a value of <em>Success</em>. Other values include <em>SuccessWithWarning</em>, <em>Failure</em>, and <em>FailureWithWarning</em>. The response array will store the actual reasons in order elements in those situations. The unique transaction ID will be stored in <strong>$response_array['TRANSACTIONID']</strong>. This would be needed for the capture phase, if using that route. Again, if you need help with updating the admin pieces, let me know.</p><p>So that&#8217;s the gist of how you would use PayPal&#8217;s Website Payments Pro instead of Authorize.net for direct payment with the second e-commerce example in the book. As already mentioned, PayPal does insist that you create an Express Checkout process, too. It&#8217;s actually slightly simpler than this code because the user&#8217;s billing and shipping information is already stored in PayPal. To integrate this option, you&#8217;d add PayPal&#8217;s Express Checkout button to your <strong>cart.php</strong> page, and that would take the user to a different page on your site, where he or she enters his or her PayPal email address and password. This is then sent to PayPal for authorization, along with the order particulars. For more, see PayPal&#8217;s documentation.</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2012/03/07/using-paypals-website-payments-pro-with-effortless-e-commerce-with-php-and-mysql/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> </channel> </rss>
<!-- Served from: www.larryullman.com @ 2012-05-21 12:56:19 by W3 Total Cache -->
