<?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; mvc</title> <atom:link href="http://www.larryullman.com/tag/mvc/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>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>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>My Yii Book Update</title><link>http://www.larryullman.com/2011/11/03/my-yii-book-update/</link> <comments>http://www.larryullman.com/2011/11/03/my-yii-book-update/#comments</comments> <pubDate>Fri, 04 Nov 2011 01:48:50 +0000</pubDate> <dc:creator>Larry</dc:creator> <category><![CDATA[MySQL]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Web Development]]></category> <category><![CDATA[books]]></category> <category><![CDATA[framework]]></category> <category><![CDATA[mvc]]></category> <category><![CDATA[yii]]></category> <category><![CDATA[yiibk]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=2853</guid> <description><![CDATA[I&#8217;ve received a few comments and questions lately about my intentions to write a book on the Yii framework. I&#8217;ve never formally discussed the idea, and so it seems like it&#8217;s about time I do so. I first started using the Yii framework about two and half years ago. I&#8217;ve never been much of a framework [...]]]></description> <content:encoded><![CDATA[<p>I&#8217;ve received a few comments and questions lately about my intentions to write a book on the <a
href="http://yiiframework.com/">Yii framework</a>. I&#8217;ve never formally discussed the idea, and so it seems like it&#8217;s about time I do so.</p><p>I first started using the Yii framework about two and half years ago. I&#8217;ve never been much of a framework person, but Yii really felt right to me, quite similar to <a
href="http://rubyonrails.com/">Ruby on Rails</a>, which I also always liked. Being a writer, after learning to use the framework, I wrote an <a
href="http://www.larryullman.com/series/learning-the-yii-framework/">introductory series on the subject</a>, which has been quite popular. In all modesty, many have suggested it&#8217;s the best documentation available. In fact, the creator of Yii liked my series so much that he listed it prominently on the official Yii documentation page (it&#8217;s now under <a
href="http://www.yiiframework.com/tutorials/">tutorials</a>). Some time after writing that series, I started thinking about writing a full book on Yii, because <a
href="http://www.larryullman.com/books/">that&#8217;s what I do</a>.</p><p>When I decided to write a book on Yii, I figured I&#8217;d self-publish it, for a couple of reasons. First, even though I have a wonderful relationship with <a
href="http://peachpit.com/">Peachpit Press</a>, I&#8217;m not sure they&#8217;d want to do a book on Yii, as the market is kind of small. Second, even if Peachpit would publish such a book, I doubt I&#8217;d make much money on the project, considering the small market. By comparison, if I self-publish, I can make 4-5 times per book what I&#8217;d make if I went through a publisher. The higher per copy amount could be enough to make up for the smaller sales, ending up with a project that&#8217;s financially worth my time to do (sorry to be crass about the money, but writing a book is a lot of work and I do have bills to pay!). Fourth, I&#8217;ve been intrigued about self-publishing for some time. And, fifth, self-publishing would give me the opportunity to distribute the book in unique formats and channels, such as a chapter at a time.</p><p>If I had my act together (which is to say, if my life were other than it is, in about ten ways), I would have been on the ball and published this book a year or more ago. Sadly, that has not been the case. I keep fairly busy work-wise, and I don&#8217;t actually have the time (due to personal constraints) to put in 40-hour weeks, so it&#8217;s really hard to add new projects, especially on the level of an entire book. Moreover, self-publishing means no guaranteed money, so I&#8217;d have to not do paying work while not making money working on the Yii book, which is a tough situation to be in.</p><p>All that being said, <em>it is still my intention to write and self-publish a book on Yii</em>. The only question is: when? This is the question I&#8217;m getting asked a lot lately. Before I do anything towards a book on Yii, I still have to:</p><ul><li>Finish my <em>Modern JavaScript: Develop and Design</em> book (which I&#8217;m weeks late on as is)</li><li>Write one more article in support of my <em>PHP and MySQL for Dynamic Web Sites: Visual QuickPro Guide (4th Edition)</em> [I've written two out of three articles, but I'm weeks late on that, too.]</li><li>Come up with a list of videos to do in support of my <em>Modern JavaScript: Develop and Design</em> book</li><li>Actually do those videos</li><li>Continue doing the Web development and other work I have for my clients</li></ul><p>So&#8230;yikes. Don&#8217;t get my wrong: I&#8217;m quite fortunate to be busy, but yikes! I&#8217;ll be crying if I haven&#8217;t finished all of the above by the end of this year, which means in theory I can begin the Yii book at the beginning of 2012. However, I have the third edition of my <em>PHP 5 Advanced: Visual QuickPro Guide</em> due at the end of April. That does give me four months, but I&#8217;d like actually make that deadline for a change (my publisher is wonderfully understanding, but&#8230;).</p><p>Also, along with writing the Yii book, I&#8217;m going to have to come up with a site and an ecommerce system and so forth (I already have the software that can output PDFs, ePubs, and mobis). If I&#8217;m being optimistic, perhaps in 2012 I can do two Yii chapters per month, but the <em>PHP 5 Advanced</em> book will need to be my first priority. I also don&#8217;t want to start the Yii book, get some people paying for it (in part or in whole), and then have the project drag out. I don&#8217;t know. We shall see.</p><p>I very much thank everyone for their interest in my writing a book on Yii and I hope to make that happen. If you follow the blog and/or subscribe to my newsletter, you&#8217;ll get updates as to how this is progressing, when and if it does actually progress.</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2011/11/03/my-yii-book-update/feed/</wfw:commentRss> <slash:comments>40</slash:comments> </item> <item><title>Using Cookies in the Yii Framework</title><link>http://www.larryullman.com/2011/06/04/using-cookies-in-the-yii-framework/</link> <comments>http://www.larryullman.com/2011/06/04/using-cookies-in-the-yii-framework/#comments</comments> <pubDate>Sat, 04 Jun 2011 14:28:06 +0000</pubDate> <dc:creator>Larry</dc:creator> <category><![CDATA[MySQL]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Web Development]]></category> <category><![CDATA[cookie]]></category> <category><![CDATA[csrf]]></category> <category><![CDATA[framework]]></category> <category><![CDATA[mvc]]></category> <category><![CDATA[security]]></category> <category><![CDATA[yii]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=2552</guid> <description><![CDATA[In a previous post, I wrote about . In this one, I&#8217;ll look at using cookies. Neither is that difficult, but as with all things regarding frameworks, the solution may not be obvious at first. And there are some ways to make use cookies in Yii in a more secure manner.To create a cookie in [...]]]></description> <content:encoded><![CDATA[<p>In a previous post, I wrote about <a
href="http://www.larryullman.com/2011/05/03/using-sessions-with-the-yii-framework/">using sessions in Yii-based sites</a>. In this one, I&#8217;ll look at using cookies. Neither is that difficult, but as with all things regarding frameworks, the solution may not be obvious at first. And there are some ways to make use cookies in Yii in a more secure manner.<span
id="more-2552"></span>To create a cookie in PHP without using a framework, you just call the <a
href="http://us.php.net/setcookie">setcookie()</a> function. To create a cookie while using the Yii framework, you don&#8217;t use <strong>setcookie()</strong>, but rather create a new element in the <strong>Yii::app()-&gt;request-&gt;cookies</strong> array. (Note that sessions are stored in <strong>Yii::app()-&gt;session</strong>, but cookies are in <strong>Yii::app()-&gt;request-&gt;cookies</strong>, because cookies are part of the HTTP request a browser makes of a Web server).</p><p>What you&#8217;ll want to do to create a cookie is create a new object of type <a
href="http://www.yiiframework.com/doc/api/1.1/CHttpCookie/">CHttpCookie</a>: Yii&#8217;s class for cookies. Here, then, is the syntax for setting a cookie in Yii:</p><pre class="brush: php; title: ; notranslate">Yii::app()-&gt;request-&gt;cookies['name'] = new CHttpCookie('name', 'value');</pre><p>You must use the same <em>name</em> value in both places, replacing it with the actual cookie name. Remember that the cookie&#8217;s name, and value, are visible to users in their browsers, so one ought to be prudent about what name you use and be extra mindful of what values are being stored.</p><blockquote><p>Tip: Because the cookie&#8217;s name must be used twice in the code, you may want to consider assigning the cookie&#8217;s name to a variable that is used in both instances instead.</p></blockquote><p>Once you&#8217;ve created a cookie, you can access it (on subsequent pages, because cookies are never immediately available to the page that set them), using <strong>Yii::app()-&gt;request-&gt;cookies['name']-&gt;value</strong>. You have to use the extra <strong>-&gt;value</strong> part, because the &#8220;cookie&#8221; being created is actually an object of type <strong>CHttpCookie</strong> (and Yii, internally, takes care of actually sending the cookie to the browser and reading the received cookie from the browser).</p><p>To test if a cookie exists, just use <strong>isset()</strong> on <strong>Yii::app()-&gt;request-&gt;cookies['name']</strong>, as you would any other variable.</p><p>To delete an existing cookie, just unset the element as you would any array element:</p><pre class="brush: php; title: ; notranslate">unset(Yii::app()-&gt;request-&gt;cookies['name']);</pre><p>To delete all existing cookies (for that site), use</p><pre class="brush: php; title: ; notranslate">Yii::app()-&gt;request-&gt;cookies-&gt;clear();</pre><p>By default, cookies will be set to expire when the browser window is closed. To change that, you need to modify the properties of the cookie. You can&#8217;t do so when you create the <strong>CHttpCookie</strong> object (i.e., the only arguments to the constructor are the cookie&#8217;s name and value), so you must separately create a new object of type <strong>CHttpCookie</strong>, to be assigned to <strong>Yii::app()-&gt;request-&gt;cookies</strong> later:</p><pre class="brush: php; title: ; notranslate">$cookie = new CHttpCookie('name', 'value');</pre><p>Then adjust the <strong>expire</strong> attribute:</p><pre class="brush: php; title: ; notranslate">$cookie-&gt;expire = time() + (60*60*24); // 24 hours</pre><p>Then add the cookie to the application:</p><pre class="brush: php; title: ; notranslate">Yii::app()-&gt;request-&gt;cookies['name'] = $cookie;</pre><p>You can manipulate other cookie properties using the above syntax: <strong>domain</strong>, <strong>httpOnly</strong>, <strong>path</strong>, and <strong>secure</strong>. Each of these correspond to the arguments to the <strong>setcookie()</strong> function. (You can also manipulate the value of the cookie through <strong>$cookie-&gt;value</strong> and the cookie&#8217;s name through <strong>$cookie-&gt;name</strong>). For example, if you want to limit a cookie to a specific domain, or subdomain, use <strong>domain</strong>; to limit it to a specific folder, use <strong>path</strong>; and to only transmit the cookie over SSL, set <strong>secure</strong> to <strong>true</strong>.</p><p>You can also improve the security of your cookies by setting Yii&#8217;s <strong>enableCookieValidation</strong> to <strong>true</strong>, in the Yii configuration file:</p><pre class="brush: php; title: ; notranslate">return array(
    'components'=&gt;array(
        'request'=&gt;array(
            'enableCookieValidation'=&gt;true,
        ),
    ),
);</pre><p>Cookie validation prevents cookies from being manipulated in the browser. To accomplish that, Yii stores a hashed representation of the cookie&#8217;s value when it gets sent, and then compares the received cookie&#8217;s value to ensure they are the same. Obviously there&#8217;s extra overhead required to do this, but in some instances, the extra effort is justified by the extra security.</p><p>Finally, one good reason to use cookies in a Yii-based site, even if the site is otherwise using sessions, is to prevent <a
href="http://en.wikipedia.org/wiki/Cross-site_request_forgery">Cross-site Request Forgery (CSRF)</a> attacks. A CSRF works like this: malicious site A has some code on it, such as an image tag whose <strong>src</strong> attribute points to a page on site B that does something meaningful: <em>http://www.example.com/page.php?action=this</em>. When any viewer loads the page on site A, the use of that <strong>src</strong> attribute has the effect of that user performing a request of the page on site B.</p><p>As an example, let&#8217;s say that an administrator at your site logs in and does whatever but doesn&#8217;t log out. The administrator therefore still has a cookie in her or his browser indicating access to the site (i.e., the user could open the browser and perform admin tasks without logging in again). Now let&#8217;s say that the <strong>src</strong> attribute on malicious site A points to a page on your site that deletes a blog posting. If the administrator with the live cookie loads that page on site A, it will have the same effect as if that administrator went to your site and requested that page directly. This is not good.</p><p>To prevent a CSRF attack on your site, first make sure that all significant form submissions use POST instead of GET. You should be using POST for any form that changes server content anyway, but a CSRF POST attack is a bit harder to pull off than a GET attack.</p><p>Second, set <strong>enableCsrfValidation</strong> to <strong>true</strong> in your configuration file:</p><pre class="brush: php; title: ; notranslate">return array(
    'components'=&gt;array(
        'request'=&gt;array(
            'enableCsrfValidation'=&gt;true,
        ),
    ),
);</pre><p>By doing this, Yii will send a cookie with a unique identifier to the user. All forms will then store that same identifier in a hidden input. The form submission will only be handled then if the two identifiers match. With the case of a CSRF attack, the two identifiers will not match because the form&#8217;s identifier will not be passed as part of the request (I hope this is clear; if not, let me know). Note that this only works if you&#8217;re using <a
href="http://www.yiiframework.com/doc/api/1.1/CHtml">CHtml</a> to create your forms (if you manually create the form tags, Yii won&#8217;t insert the necessary code for preventing CSRF attacks).</p><p>The most important thing to remember about cookies, which I&#8217;ve already stated, is that cookies are visible to the user in the browser. And unless you&#8217;re using SSL for the cookies, they are also visible to anyone else while being transmitted back and forth between the server and the client (which happens on every page request). So be careful of what gets stored in a cookie! If the data is particularly sensitive, use sessions instead of cookies.</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2011/06/04/using-cookies-in-the-yii-framework/feed/</wfw:commentRss> <slash:comments>10</slash:comments> </item> <item><title>Yii vs Zend vs Code Igniter Compared</title><link>http://www.larryullman.com/2011/06/01/yii-vs-zend-vs-code-igniter-compared/</link> <comments>http://www.larryullman.com/2011/06/01/yii-vs-zend-vs-code-igniter-compared/#comments</comments> <pubDate>Wed, 01 Jun 2011 17:05:39 +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> <category><![CDATA[zend]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=2593</guid> <description><![CDATA[I&#8217;m often asked why I like the Yii framework, which is easy enough to answer: for starters it requires PHP 5 and uses jQuery natively. Then I like how it auto-generates a lot of code and folders for you. From there, it just kind of works and makes sense to me. In other words, Yii [...]]]></description> <content:encoded><![CDATA[<p>I&#8217;m often asked why I like the <a
href="http://www.yiiframework.com">Yii framework</a>, which is easy enough to answer: for starters it requires PHP 5 and uses <a
href="http://www.jquery.com">jQuery</a> natively. Then I like how it auto-generates a lot of code and folders for you. From there, it just kind of works and makes sense to me. In other words, Yii feels right. And unless you really investigate the framework&#8217;s underpinnings, how it feels (and can you get it to do what you need to do) is a large part of the criteria in making a selection.</p><p>The question I can&#8217;t really answer is what advantage Yii has over the <em>X</em> framework. The only other PHP framework I&#8217;ve used extensively is the <a
href="http://framework.zend.com">Zend framework</a>. The Zend framework has a lot going for it and is worth anyone&#8217;s consideration. To me, its biggest asset is that you can use it piecemeal and independently (I&#8217;ve often used components of the Zend Framework in Yii-based and non-framework-based sites), but I just don&#8217;t like the Zend Framework as the basis of an entire site. It requires a lot of work, the documentation is overwhelming while still not being that great, and it just doesn&#8217;t &#8220;feel&#8221; right to me.</p><p>Anyway, the point of this post is that there&#8217;s a <a
href="http://www.sheldmandu.com/php/php-mvc-frameworks/yii-vs-zend-vs-code-igniter-compared">nice article at SHELDMANDU</a> from back in January in which the author does a great job of comparing the Yii framework with the Zend framework and <a
href="http://codeigniter.com/">Code Igniter</a> (I&#8217;ve heard many good things about Code Igniter). Moreover, the author lays out some of his criteria for what he wants in a framework, has reasonable and detailed critiques, and also specifically details why he didn&#8217;t consider other frameworks in his comparison. If you&#8217;re looking into frameworks, spend five minutes reading that article to help educate yourself as to what considerations you should have in mind during your research.</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2011/06/01/yii-vs-zend-vs-code-igniter-compared/feed/</wfw:commentRss> <slash:comments>18</slash:comments> </item> <item><title>Using Sessions with the Yii Framework</title><link>http://www.larryullman.com/2011/05/03/using-sessions-with-the-yii-framework/</link> <comments>http://www.larryullman.com/2011/05/03/using-sessions-with-the-yii-framework/#comments</comments> <pubDate>Tue, 03 May 2011 01:16:56 +0000</pubDate> <dc:creator>Larry</dc:creator> <category><![CDATA[MySQL]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Web Development]]></category> <category><![CDATA[cookie]]></category> <category><![CDATA[framework]]></category> <category><![CDATA[mvc]]></category> <category><![CDATA[session]]></category> <category><![CDATA[yii]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=2353</guid> <description><![CDATA[I haven&#8217;t written much about the Yii framework lately, mostly because I&#8217;ve been working night and day on the fourth edition of my &#8220;PHP and MySQL for Dynamic Web Sites: Visual QuickPro Guide&#8221; book, due out late summer 2011. So I figured I&#8217;d put together another little blurb on the Yii framework (by regularly putting [...]]]></description> <content:encoded><![CDATA[<p>I haven&#8217;t written much about the <a
href="http://www.yiiframework.com">Yii framework</a> lately, mostly because I&#8217;ve been working night and day on the fourth edition of my &#8220;PHP and MySQL for Dynamic Web Sites: Visual QuickPro Guide&#8221; book, due out late summer 2011. So I figured I&#8217;d put together another little blurb on the Yii framework (by regularly putting out posts on Yii, it&#8217;ll be that much easier when I go to write a book on Yii later this summer). In this post, I&#8217;m going to talk about using sessions Yii-based sites (in a separate post, I&#8217;ll discuss cookies). While not at all hard, the topic, like quite a few things, is not obvious in Yii, or well documented.</p><p><span
id="more-2353"></span></p><p>The first thing to know about using sessions in Yii is that you don&#8217;t have to do anything to enable them, which is to say you don&#8217;t have to invoke <strong>session_start()</strong>, as you would in a standard PHP script. This is the behavior with Yii&#8217;s <strong>autoStart</strong> session property set to <em>true</em>, which is the default. Even without using <strong>session_start()</strong>, you could, of course, make use of the <strong>$_SESSION</strong> superglobal array, as you would in a standard PHP script, but it&#8217;s best when using frameworks to make total use of the framework. The Yii equivalent to <strong>$_SESSION</strong> is <strong>Yii::app()-&gt;session</strong>:</p><pre class="brush: php; title: ; notranslate">Yii::app()-&gt;session['var'] = 'value';
echo Yii::app()-&gt;session['var']; // Prints &quot;value&quot;</pre><p>And that&#8217;s all there is to it. To remove a session variable, apply <strong>unset()</strong>, as you would to any other variable:</p><pre class="brush: php; title: ; notranslate">unset(Yii::app()-&gt;session['var']);</pre><p>So&#8230;nothing really unexpected there, once you know where to find the session data. The more complex consideration is how to configure sessions for your Yii application. You can do so using the primary configuration file (<strong>protected/config/main.php</strong>). Within that, you would add a &#8220;session&#8221; element to the &#8220;components&#8221; array, wherein you customize how the sessions behave. The key attributes are:</p><ul><li><strong>autoStart</strong>, which defaults to <em>true</em> (i.e., always start sessions)</li><li><strong>cookieMode</strong>, with acceptable values of <em>none</em>, <em>allow</em>, and <em>only</em>, equating to: don&#8217;t use cookies, use cookies if possible, and only use cookies; defaults to <em>allow</em></li><li><strong>cookieParams</strong>, for adjusting the session cookie&#8217;s arguments, such as its lifetime, path, domain, and HTTPS-only</li><li><strong>gCProbability</strong>, for setting the probability of garbage collection being performance, with a default of 1, as in a 1% chance</li><li><strong>savePath</strong>, for setting the directory on the server used as the session directory, with a default of <em>/tmp</em></li><li><strong>sessionName</strong>, for setting the session&#8217;s, um, name, which defaults to <em>PHPSESSID</em></li><li><strong>timeout</strong>, for setting after how many seconds a session is considered idle, which defaults to 1440</li></ul><p>For all of these, the default values are the same as those that PHP sessions commonly run using, except for <strong>autoStart</strong>.</p><p>If your site will not be using sessions at all, you would want to disable them by adding this code to the &#8220;components&#8221; section of <strong>protected/config/main.php</strong>:</p><pre class="brush: php; title: ; notranslate">'session' =&gt; array (
    'autoStart' =&gt; false,
),</pre><p>If you are using sessions, for security purposes, you may want to change the session&#8217;s name, always require cookies, and change the save path:</p><pre class="brush: php; title: ; notranslate">'session' =&gt; array (
    'sessionName' =&gt; 'Site Access',
    'cookieMode' =&gt; 'only',
    'savePath' =&gt; '/path/to/new/directory',
),</pre><p>The save path, in case you&#8217;re not familiar with it, is where the session data is stored on the server. By default, this is a temporary directory, globally readable and writable. Every site running on the sever, if there are many (and shared hosting plans can have dozens on a single server), share this same directory. This means that any site on the server can read any other site&#8217;s stored session data. For this reason, changing the save path to a directory within your own site can be a security improvement. Alternatively, you can store the session data in a database. To do that, add this code to the &#8220;components&#8221; section of <strong>protected/config/main.php</strong>:</p><pre class="brush: php; title: ; notranslate">'session' =&gt; array (
    'class' =&gt; 'system.web.CDbHttpSession',
    'connectionID' =&gt; 'db',
    'sessionTableName' =&gt; 'actual_table_name',
),</pre><p>If you choose this route, Yii will automatically create the table if it does not exist. You can also perform any of the other session configuration changes in that code block, too.</p><p>So&#8230;what else? Frequently, for debugging purposes, and sometimes to store it in the database, I like to know the user&#8217;s current session ID. That value can be found in <strong>Yii::app()-&gt;session-&gt;sessionID</strong>.</p><p>Finally, when the user logs out, you may want to formally eradicate the session. To do so, call <strong>Yii::app()-&gt;session-&gt;clear()</strong> to remove all of the session variables. Then call <strong>Yii::app()-&gt;session-&gt;destroy(</strong>) to get rid of the actual data stored on the server.</p><p>And that&#8217;s what there is to know about using sessions with Yii, at least that&#8217;s all the key information. I hope this helps you with your Yii-based applications. As always, thanks for reading and let me know if you have any comments or questions.</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2011/05/03/using-sessions-with-the-yii-framework/feed/</wfw:commentRss> <slash:comments>37</slash:comments> </item> <item><title>Rendering View Files in Yii</title><link>http://www.larryullman.com/2011/02/15/rendering-view-files-in-yii/</link> <comments>http://www.larryullman.com/2011/02/15/rendering-view-files-in-yii/#comments</comments> <pubDate>Tue, 15 Feb 2011 16:08:58 +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[view]]></category> <category><![CDATA[yii]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=2139</guid> <description><![CDATA[In the MVC architecture, the Controller reacts to a user request. In doing so, the Controller often loads an instance of a particular Model and then renders a specific View. &#8220;Rendering&#8221; just means compiling all the pieces together, including static text (HTML and such) and the output from executed PHP code. For example, when a [...]]]></description> <content:encoded><![CDATA[<p>In the MVC architecture, the Controller reacts to a user request. In doing so, the Controller often loads an instance of a particular Model and then <em>renders</em> a specific View. &#8220;Rendering&#8221; just means compiling all the pieces together, including static text (HTML and such) and the output from executed PHP code. For example, when a user goes to a page for updating a record, the Controller loads the associated record, and then renders the &#8220;update&#8221; View, which will display the pre-populated form:</p><pre class="brush: php; title: ; notranslate">public function actionUpdate($id) {
    $data=$this-&gt;loadModel($id);

    $this-&gt;render('update',array(
        'model'=&gt;$data
    ));
}</pre><blockquote><p>Note: That method would also have code in it for handling the submission of the update form, but I&#8217;m trying not to complicate the discussion.</p></blockquote><p>As you can see in that code, the <strong>render()</strong> method, defined in the <strong>CController</strong> class, is how a View file is chosen for rendering. The first argument to the method is the View file to be rendered, without its <strong>.php</strong> extension. The <strong>render()</strong> method will render the View file within the appropriate layout file. In other words, the View file will be rendered with its context. The above code renders <strong>update.php</strong>, for the associated Controller, wrapped within the <strong>views/layouts/main.php</strong> layout file (the default).</p><p>The second argument to <strong>render()</strong> is an array of data that can be sent to the View file. In the above code, the Model instance is being passed along. In <strong>update.php</strong>, references to the <strong>$model</strong> variable will refer to the loaded data (note that the View gets its variable names from the indexes used in the array).</p><p>The <strong>render()</strong> method takes an optional third argument, which is a Boolean indicating if the rendered result should be returned to the Controller instead of sent to the Web browser. This would be useful if you wanted to render the page and then send the output in an email or write it to a text file on the server (to act as a cached version).</p><p>Sometimes you&#8217;ll want to render a View file without incorporating the layout. To do that, invoke <strong>renderPartial()</strong>. For example, both the <strong>update.php</strong> and <strong>create.php</strong> View files, auto-generated by Yii, just provide a context, and then include the form file:</p><pre class="brush: php; title: ; notranslate">&lt;?php echo $this-&gt;renderPartial('_form', array('model'=&gt;$model)); ?&gt;</pre><p>Since the initial View file will have already be rendered within the layout context, the layout shouldn&#8217;t be rendered again. The <strong>renderPartial()</strong> method will render just the named View file. Its second argument, as with <strong>render()</strong>, can be used to pass data to the View file. In the above, the Model instance is passed along.</p><blockquote><p>Tip: The <strong>renderPartial()</strong> method is also used for Ajax calls, where the layout isn&#8217;t appropriate.</p></blockquote><p>As mentioned already, the file being rendered comes from the directory associated with the current Controller. For example, when updating an <strong>Employee</strong> record, the URL is something like <span
style="text-decoration: underline;">www.example.com/index.php/employee/update/id/23</span>. This calls the <strong>actionUpdate()</strong> method of the <strong>EmployeeController</strong> class (whose code is partially shown above). That method renders the &#8220;update&#8221; View, which is to say <strong>protected/views/employee/update.php</strong>. But there are rare cases where you&#8217;ll need to render View files from other subdirectories. For example, you may want to include a search form on a page, with that form found within another View directory. To change the reference point, start the View reference with a double slash, which means to start in the <strong>views</strong> folder. Then indicate the subdirectory and file, still omitting the extension:</p><pre class="brush: php; title: ; notranslate">&lt;?php echo $this-&gt;renderPartial('//search/_form'); ?&gt;</pre><p>And that&#8217;s all there is to it!</p><p>View rendering is one of the most important concepts to grasp in an MVC design. Fortunately, it&#8217;s not that hard to follow in Yii. Just remember that if you want your layout file, use <strong>render()</strong>. If not, use <strong>renderPartial()</strong>. If you need to pass data to the View file, use the second argument to send along an array, whose indexes will become the names of the variables within the View. Finally, if you need to change the include path, begin with a double slash.</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2011/02/15/rendering-view-files-in-yii/feed/</wfw:commentRss> <slash:comments>29</slash:comments> </item> <item><title>What is Larry Thinking? #36 =&gt; Becoming a Better Programmer and More!</title><link>http://www.larryullman.com/2011/02/01/what-is-larry-thinking-36-becoming-a-better-programmer-and-more/</link> <comments>http://www.larryullman.com/2011/02/01/what-is-larry-thinking-36-becoming-a-better-programmer-and-more/#comments</comments> <pubDate>Tue, 01 Feb 2011 14:45:22 +0000</pubDate> <dc:creator>Larry</dc:creator> <category><![CDATA[MySQL]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Ruby]]></category> <category><![CDATA[Web Development]]></category> <category><![CDATA[mvc]]></category> <category><![CDATA[newsletter]]></category> <category><![CDATA[yii]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=2260</guid> <description><![CDATA[In this edition&#8230; About This Newsletter On the Web => Colibri for Windows On the Web => &#8220;Learning the Yii Framework&#8221; Series in French! On the Blog => Creating Forms with the Yii Framework On the Blog => Markdown and MultiMarkdown Q&#38;A => What happened to Ruby on Rails? Q&#38;A => What is the Benefit [...]]]></description> <content:encoded><![CDATA[<p> In this edition&#8230;</p><ul><li><a
href="#about">About This Newsletter</a></li><li><a
href="#web1">On the Web => Colibri for Windows</a></li><li><a
href="#web2">On the Web => &#8220;Learning the Yii Framework&#8221; Series in French!</a></li><li><a
href="#blog1">On the Blog => Creating Forms with the Yii Framework</a></li><li><a
href="#blog2">On the Blog => Markdown and MultiMarkdown</a></li><li><a
href="#qa1">Q&amp;A => What happened to Ruby on Rails?</a></li><li><a
href="#qa2">Q&amp;A => What is the Benefit of the Model in MVC?</a></li><li><a
href="#thinking">What is Larry Thinking => Becoming a Better Programmer</a></li><li><a
href="#news">Larry Ullman&#8217;s Book News => &#8220;PHP for the Web&#8221;, &#8220;PHP and MySQL for Dynamic Web Sites&#8221;, and More!</a></li></ul><h2 id="about">About This Newsletter</h2><p>No real theme to this newsletter: a couple of links to interesting things online, recommendations of two blog postings to consider, answers to two recently submitted questions, and some news. I turned a frequently asked question into a &#8220;What is Larry Thinking?&#8221; topic: how to become a better programmer. I&#8217;ll follow up on that topic in a future newsletter, too. Other forthcoming subjects include: starting a new Web site/business, making a career out of programming, and how to organically grow a Web site.</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="web1">On the Web => Colibri for Windows</h2><p>As you may know, I primarily use a Mac, so I tend to be less aware of the good stuff available for those of you—okay, the <em>majority</em> of you—on Windows. One Mac product that I used to rely heavily upon is <a
href="http://qsapp.com/">QuickSilver</a>. QuickSilver is an application and document launcher, system navigator, utility, jack-of-all-trades. QuickSilver is free, extendable, and quite excellent. Unfortunately, or fortunately for him, the developer that created QuickSilver was hired by Google to create a somewhat similar product for them called <a
href="http://code.google.com/p/qsb-mac/">Quick Search Box for Mac</a>. So I have since returned to <a
href="http://www.obdev.at/products/launchbar/index.html">LaunchBar</a>, with which I&#8217;m also quite pleased. But this blip isn&#8217;t about good Mac software, this is about <a
href="http://colibri.leetspeak.org/">Colibri</a> for Windows.</p><p>I have no idea where or how, but I recently came across Colibri as a Windows equivalent to QuickSilver. Naturally this caught my attention. And although I haven&#8217;t used it myself, I thought it worth mentioning, because if it&#8217;s anything like QuickSilver or LaunchBar, some of you Windows power users will really appreciate it. With Colibri, you can control iTunes, interact with Firefox, perform Web searches, launch applications, and more, all from an interface that appears by pressing the right key combination. Oh, and it&#8217;s free! One negative from the research I&#8217;ve done is that the documentation isn&#8217;t great, at least not online. But still, Colibri may be worth considering.</p><h2 id="web2">On the Web => &#8220;Learning the Yii Framework&#8221; Series in French!</h2><p>Nico, from <a
href="http://www.memorandom.fr">Mémorandom</a>, recently contacted me about translating my popular <a
href="http://www.larryullman.com/series/learning-the-yii-framework/">Learning the Yii Framework</a> into French and publishing it on that site. I&#8217;m pleased to say that the first five parts of the series have already been translated and are available online:</p><ul><li><p><a
href="http://www.memorandom.fr/php/introduction-au-framework-yii/">Introduction to the Yii Framework</a></p></li><li><p><a
href="http://www.memorandom.fr/php/commencer-avec-yii-framework/">Getting Started with the Yii Framework</a></p></li><li><p><a
href="http://www.memorandom.fr/php/configuration-de-yii/">Configuring Yii</a></p></li><li><p><a
href="http://www.memorandom.fr/php/definir-une-base-de-donnees-pour-notre-application-yii/">Defining Databases for the Yii Application</a></p></li><li><p><a
href="http://www.memorandom.fr/php/creer-les-modeles-les-vues-et-les-controleurs-dans-yii/">Creating Models, Views, and Controllers in Yii</a></p></li></ul><p>The posted translation should hopefully help expand Yii&#8217;s international influence. My thanks to Nico for the nice words on my series and for the work in translating it!</p><h2 id="blog1">On the Blog => Creating Forms with the Yii Framework</h2><p>HTML forms are one of the key pieces of any Web site, providing an easy way to get data from the user. But, as is the case with many things, creating forms while using a framework such as Yii is significantly different than creating forms using standard HTML alone. <a
href="http://www.larryullman.com/2011/01/20/creating-forms-with-the-yii-framework/">In a recent post</a>, I covered what you need to know to get started creating HTML forms when using the Yii framework.</p><h2 id="blog2">On the Blog => Markdown and MultiMarkdown</h2><p>In previous newsletters I&#8217;ve made reference to Markdown and MultiMarkdown, two of my favorite new technologies (well, new to me). The one is an extension of the other and both allow you to write more naturally, without concern for formatting, and then output that text in HTML and other formats. I&#8217;ve been using Markdown for my newsletter for a couple of months now and plan on using MultiMarkdown when I begin self-publishing books this year.<br
/> You can read a quick introduction to both technologies, and see where to head for more information, <a
href="http://www.larryullman.com/2011/01/08/markdown-and-multimarkdown/">in this blog post</a>.</p><h2 id="qa1">Q&amp;A => What happened to Ruby on Rails?</h2><p>Jason sent me this question, pointing out that &#8220;It was all the rage a while back&#8221;. True, true. So what did happen?</p><p>First, I&#8217;ll say that I adore <a
href="http://www.ruby-lang.org/">Ruby</a>. It&#8217;s a beautiful language, odd as that may sound. If I need to create non-graphical utilities or scripts to be executed via a command line, Ruby is my language of choice. Ruby has great power yet simplicity, and is more object-oriented than most (e.g., any number in Ruby is itself an object). And <a
href="http://rubyonrails.org/">Rails</a> is a great framework for doing Web development. It does a lot of the work for you and has outstanding features. In fact, Rails recently came out with version 3, which was a major revamping, integrating features that cropped up in Ruby-based alternatives to the Rails framework.</p><p>Anyway, I suspect part of the reason that Rails doesn&#8217;t get the attention it once did is that it&#8217;s no longer &#8220;new&#8221;. Secondarily, I think the impression of Rails was severely damaged by what happened with Twitter. Twitter was originally written using Ruby on Rails but Twitter got to a point where the site wasn&#8217;t able to handle its demand. Rightly or not (probably some of both), Ruby on Rails took the brunt of the bad press for the outages. I would argue that one can&#8217;t use Twitter as a reasonable benchmark, though, as very few—perhaps only a handful—of sites have the same level of activity as Twitter. I suspect that most sites would crash if they started seeing that kind of demand. Poor scalability is not a problem of Ruby on Rails. In fact, honestly, I don&#8217;t know that <em>any</em> technology has inherently poor scalability, but that all technologies will degrade under high loads, if not optimized for demanding conditions.</p><p>To be fair, performance is a concern whenever you use a framework. Framework-based applications, by definition, are going to be more bloated and slower than non-framework applications. That&#8217;s just the way it is and will be. In turn, one gets much faster development with a framework. In any case, I know Twitter eventually replaced their Ruby on Rails code with something else (written in <a
href="http://www.scala-lang.org/">Scala</a>, I believe), but Groupon and Hulu use Ruby on Rails, and these are also very demanding sites.</p><p>Finally, as for myself, despite my affection for Ruby and Ruby on Rails, the reason I don&#8217;t regularly use RoR for Web sites is because there&#8217;s now a good, comparable PHP framework (for me, that&#8217;s <a
href="http://www.yiiframework.com">Yii</a>). I had been programming with PHP for several years before learning Ruby and Rails. When I came across RoR, there was no PHP framework like it. But I&#8217;ve since found, and grown quite fond of, Yii, so my need for a quick development Web framework has been met, allowing me to use PHP, the language that I&#8217;m still most comfortable with.</p><h2 id="qa2">Q&amp;A => What is the Benefit of the Model in MVC?</h2><p>The MVC design pattern, short for &#8220;Model, View, Controller&#8221;, has become an extremely common way to write software and is used by most, if not all, major frameworks. But the MVC approach is not necessarily intuitive and can be confusing, or simply hard to properly implement, for beginners. Brett, for example, sent in this very reasonable question:</p><blockquote><p>&#8220;Views and Controllers make sense to me, but have a Model to pull out data and then to have a<br
/> View call it, doesn&#8217;t seem to flow that well in my head. What are the benefits of using Models?&#8221;</p></blockquote><p>In case you&#8217;re not familiar with MVC, the View is what the user sees and interacts with. On a Web site, this means HTML, with a dab of PHP embedded as necessary (e.g., to echo the value of a given variable). The Model represents a set of data. Often a Model corresponds to a particular database table, with an instance of the Model representing a particular row from that table. Models can also represent data sets not being permanently stored, such as the contents of a contact form, which get emailed instead. The Controller is the agent between the View and the Model. The Controller responds to user actions, such as requesting a specific page (in which case the Controller loads any necessary Model and then renders the proper View) or handling a form submission (in which case the Controller may create a new instance of a Model based upon the submitted data, then save the Model, and then render a different View). An important aspect of MVC is that Controllers should actually be lightweight, in terms of code. The applicable adage is &#8220;thin Controllers, fat Models.&#8221; The most common design error by beginning MVC-ers (?) is to put too much logic and functionality into the Controller, instead of in the Model where it belongs. But why?</p><p>Let&#8217;s quickly think about the Controller. The Controller responds to user actions and quite frequently then loads an instance of a Model which the Controller then passes to the View. Much of the Controller logic is not really particular to a given application, but rather slight variations on common themes. With a site for managing employees, the Controller&#8217;s actions would entail: listing all employees, viewing a particular employee, searching for employees, adding a new employee, updating an existing employee, and deleting a particular employee. Now say the site is for managing an inventory of products (like on an e-commerce site). In that case, the Controller&#8217;s actions include: listing all products, viewing a particular product, searching for products, adding new products, updating existing products, and deleting existing products, among others. As you can see, there&#8217;s a lot of repetition here, the only difference being the swap of &#8220;employee&#8221; for &#8220;product&#8221;. This is to say, the only difference is the Model itself. And that&#8217;s why the Model is so critical: because it is the heart of an application. When you&#8217;re deciding what a site is about, and when you&#8217;re designing the database, you&#8217;re dealing with the Model. The same Model will be used by many different Controller actions and View files. So let&#8217;s look at the Model in detail&#8230;</p><p>The Model represents the data, but what does that mean? It means, for one, that a Model defines the properties for an object, like a &#8220;user&#8221; object has a first name, last name, email address, password, etc. The Model also defines the validation routines that any data set must pass: the email address must be a valid email address, the user level must be an integer, the date entered value is the current moment upon insert, etc. Whether a new Model is being created or an existing Model is being updated, the same validation rules will apply.</p><p>Models also sometimes have custom functions for returning formatted properties. Models shouldn&#8217;t output HTML, but a user Model might have a function that returns the user&#8217;s name in the format <em>Last Name, First Name MI.</em>. Or a user Model might have a &#8220;member since&#8221; function that returns the user&#8217;s registration date in a particular format (not the database timestamp). By putting this functionality in the Model, any View can make use of it. If that functionality were defined in a Controller or View, then only that Controller or View could benefit.</p><p>Just as the majority of Controller code may be the same from site to site, some of the Models can be exactly the same from one site to another, or just slightly different. If you&#8217;ve created a user Model that does everything you need it to do, it&#8217;s likely that the same Model can be used on multiple sites (this, of course, is a benefit of object-oriented programming in general). With the MVC architecture, the biggest differences from one project to the next are therefore the Models you define and the corresponding Views.</p><p>Coincidentally, the Yii framework&#8217;s site just posted a nice article titled <a
href="http://www.yiiframework.com/doc/guide/1.1/en/basics.best-practices">Best MVC Practices</a>, which you may benefit from reading, whether you use Yii or not.</p><h2 id="thinking">What is Larry Thinking => Becoming a Better Programmer</h2><p>How one becomes a good programmer is one of the most common questions I see, especially from those just getting started. A reader purchases one of my books because they want to learn X, and then they want to know how long before they&#8217;re an expert programmer. The answer to that particular question—how long—is short and sweet: I have no idea. It really depends upon who you are, what you already know, how you learn, and so forth. But many people, when they ask you a question, don&#8217;t care for the &#8220;I have no idea&#8221; answer, even if, or especially, if that&#8217;s the correct answer. So rather than answer <em>that</em> question, I thought I&#8217;d take a moment to discuss the more appropriate question of &#8220;How do I become a better programmer?&#8221; The key is &#8220;better&#8221; as opposed to &#8220;good,&#8221; &#8220;expert,&#8221; &#8220;master,&#8221; and the like.</p><p>Perhaps it&#8217;s merely semantics, but one shouldn&#8217;t aspire to be a good programmer, but rather a <em>better</em> programmer. Like, well, almost every job, a programmer does not have a fixed end that one gets to. I&#8217;ve been programming actively for going on 12 years now and, whether I&#8217;m currently a good programmer or not, my hope is that next month I&#8217;ll be a better programmer than I am today. So how do I, or anyone, work towards being a better programmer?</p><h3>Read. Do. Review.</h3><p>Pithy things are easier to remember and just sound more true, so I&#8217;ve assembled all my thoughts into those three words: Read. Do. Review.</p><h4>Read.</h4><p>There are plenty of tasks you can pull off without reading a thing, such as changing a tire or unclogging a sink, but you can&#8217;t learn to program without reading something: a book, a manual, articles, whatever. Programming simply does not allow for blind guesses. Now clearly, my books are the best way to learn anything and should always be your first stop on a new path. This cannot be denied. (I really am joking.) But even after reading all of my books multiple times over, there&#8217;s probably a benefit of reading other writers&#8217; books (blasphemy), to get a different perspective. Assuming you&#8217;re a book-reader type, that is.</p><p>Books do three things well. First, they can teach beginners effectively. Second, they can show how to apply knowledge. Third, they provide a cohesive body of information. I&#8217;m a book person and a book writer, so I&#8217;m completely biased, but I think that reading books about programming is always for the best. I still read books by other writers, even if they&#8217;re on the same subject and targeting the same audience as some of my books. Always good to see what others are thinking!</p><p>I mention manuals second for three reasons. First, not all programming languages or technologies have actual manuals, let alone good ones (the PHP manual is pretty good, in my opinion). Second, manuals tend to promote syntax and functionality above real-world implementation. Third, manuals tend to be written by committee, thereby lacking cohesion. On the other hand, in theory, manuals will always be the most up to date of the available options.</p><p>Articles are a great way to learn new tricks, of course. You might think this means reading an article on a specific subject only if you want to learn about that subject, but you might get some value by seeing tangential code. For example, say an article is on creating an RSS feed using PHP and MySQL. You might not need to do this, but in reading the article, you could learn something about PHP and MySQL, about XML, and so forth. And again, you&#8217;d get a different writer&#8217;s perspective and approach.</p><h4>Do.</h4><p>The second step is to simple: program. You can&#8217;t really learn or improve without doing. If you don&#8217;t have actual programming work to do, then come up with your own idea and implement it. In a way, programmers, Web developers, and the like are quite fortunate, as they can practice, learn new things, create functional projects, etc., without spending a dime (or without spending much money). Many other professions, such as architects, don&#8217;t have that luxury. So take advantage of that freedom!</p><h4>Review.</h4><p>I suspect most programmers focus on the &#8220;doing&#8221; and spend very little time on the &#8220;reviewing,&#8221; which I believe is probably more important in the long run. I don&#8217;t mean testing, which is necessary, too, but actual code reviews. Are the comments still thorough and accurate? Does the code make assumptions? Are errors handled gracefully? Is the code properly formatted? Is it consistent in terms of formatting, syntax, variable names, and the like? Most programmers, in time, can make things work. It&#8217;s these other points that differentiate the average programmer from a better one. But don&#8217;t stop after reviewing your code&#8230;</p><p>You should review other people&#8217;s code. See what they did. Does it make sense? Does it adhere to the same principles just outlined? What does that code do differently than the code you&#8217;d write? Is one approach better? If so, why? I&#8217;ve become a better programmer (and a better writer) by providing support in <a
href="http://www.larryullman.com/forum/">my forums</a>. In looking at what other people did, and helping them solve problems, I&#8217;ve learned a ton. And I know that the handful of other people that are kind enough to donate their time to assist feel this way as well (and my unending gratitude to them).</p><p>A key learning tool when reviewing code is explaining what code does. There&#8217;s a related debugging approach called <a
href="http://www.larryullman.com/2010/12/04/rubber-duck-debugging/">rubber duck debugging</a> that&#8217;s similar to what I&#8217;m suggesting here. One level of programming knowledge is getting something to work. A higher level is understanding <em>why</em> it works. An even higher level is being able to <em>explain why</em> it works. I know I&#8217;ve become a better programmer by writing books, although that&#8217;s a pretty steep and unreasonable step for many to take! A few times, though, as I write a book I&#8217;m explaining why I used such and such code, and in the process of explaining, I realized that the approach could be improved. You don&#8217;t actually have to write a book or sit someone down, but go through code some time and try to explain why it&#8217;s doing what it&#8217;s doing. You&#8217;ll learn a lot.</p><h4>And&#8230;</h4><p>In a subsequent newsletter, I&#8217;ll write a bit about what general and specific skills are critical to being a better programmer, but I wanted to just focus on the process of improving here. What did I omit? Formal training and certification. Formal training, be it a school course or not, is a great way to become a better programmer, which I think goes without saying. Or it should be a great way, as not all classes or teachers are alike (true for books, as well). As for certifications, I understand they can help you get a job, but I don&#8217;t put much faith in passing a certification test as a way of becoming a better programmer. You can certainly learn some technicalities that way, but I doubt you&#8217;ll learn that much in terms of real-world knowledge and the ability to apply information.</p><h2 id="news">Larry Ullman&#8217;s Book News => &#8220;PHP for the Web&#8221;, &#8220;PHP and MySQL for Dynamic Web Sites&#8221;, and More!</h2><p>As mentioned in my previous two newsletters, I&#8217;ve been writing some articles and blog posts for <a
href="http://www.Peachpit.com">Peachpit Press&#8217;s Web site</a>, all supporting my <a
href="http://www.larryullman.com/books/effortless-e-commerce-with-php-and-mysql/">Effortless E-Commerce with PHP and MySQL</a> book. I&#8217;ll post links to them on my Web site, and in future newsletters, as they go live.</p><p>I&#8217;ve wrapped the first draft of the the fourth edition of &#8220;PHP for the Web: Visual QuickStart Guide&#8221; and am almost through with the rewrites. Along with fixing any minor problems, updating the code for the latest version of PHP, and adding a &#8220;Review and Pursue&#8221; section to the end of each chapter, I&#8217;ve been able to add a new chapter. That chapter will replace the original Chapter 13, &#8220;Regular Expressions,&#8221; as the <strong>ereg()</strong> function has been deprecated in PHP 5.3. The new chapter is called &#8220;Putting It All Together&#8221; and will show how to use everything covered in the book to assemble a mini-Web application, with authentication and full <em>CRUD</em> (Create, Retrieve, Update, and Delete) functionality. The chapter is similar to the three popular example chapters in my &#8220;PHP and MySQL for Dynamic Web Sites: Visual QuickPro Guide&#8221; book, although using a different example.</p><p>In February, I start writing the fourth edition of my &#8220;PHP and MySQL for Dynamic Web Sites: Visual QuickPro Guide.&#8221; It will also have a &#8220;Review and Pursue&#8221; section added to the end of each chapter. I&#8217;m also going to clean it up a bit, and remove references to PHP 6, which, in the time from when I started writing the third edition to started writing the fourth edition, went from about 50% complete to limbo to non-existent. So that&#8217;s the last time I&#8217;m going to try to be that far out ahead of the curve.</p><p>I am also planning on working on my self-published JavaScript book starting in February as well. I&#8217;ll try to dedicate some time to it and, as I&#8217;m publishing it myself and writing it using MulitMarkdown, I&#8217;ll be able to post free, HTML sections from the book online as I go. Thanks to everyone for their continued support and interest on this new book!</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2011/02/01/what-is-larry-thinking-36-becoming-a-better-programmer-and-more/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Yii 1.1.6 Released</title><link>http://www.larryullman.com/2011/01/25/yii-1-1-6-released/</link> <comments>http://www.larryullman.com/2011/01/25/yii-1-1-6-released/#comments</comments> <pubDate>Tue, 25 Jan 2011 22:37:46 +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=2243</guid> <description><![CDATA[Version 1.1.6 of the Yii framework was released a few days ago. Along with bug fixes, 1.1.6 includes a couple of new features, most notably database migration and a new Query Builder. Database migration is a feature that comes from Ruby on Rails (well, that&#8217;s where I first heard of it) and it allows for [...]]]></description> <content:encoded><![CDATA[<p>Version 1.1.6 of the <a
href="http://www.yiiframework.com/">Yii framework</a> was released a few days ago. Along with bug fixes, 1.1.6 includes a couple of new features, most notably <a
href="http://www.yiiframework.com/doc/guide/1.1/en/database.migration">database migration</a> and a new <a
href="http://www.yiiframework.com/doc/guide/1.1/en/database.query-builder">Query Builder</a>. Database migration is a feature that comes from <a
href="http://www.rubyonrails.com">Ruby on Rails</a> (well, that&#8217;s where I first heard of it) and it allows for better version control. Basically database migration allows you to associate database changes with versions, so that you can better sync updates to the PHP code and the underlying database. It&#8217;s a useful tool for projects being developed by a team or in stages.</p><p>The new Query Builder is an object-oriented way to create custom SQL statements. This isn&#8217;t really a new feature (in the sense of allowing you to do something you couldn&#8217;t do before) but lets you do something you might commonly do but in a different way. See the above link for a thorough discussion and demonstration.</p><p>For some reason, the 1.1.6 release of Yii includes an article on <a
href="http://www.yiiframework.com/doc/guide/1.1/en/basics.best-practices">Best MVC Practices</a>. This isn&#8217;t really part of the framework itself, but is a useful read for anyone using Yii or other MVC approaches.</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2011/01/25/yii-1-1-6-released/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>More of &#8220;Learning the Yii Framework&#8221; Series in French</title><link>http://www.larryullman.com/2011/01/23/more-of-learning-the-yii-framework-series-in-french/</link> <comments>http://www.larryullman.com/2011/01/23/more-of-learning-the-yii-framework-series-in-french/#comments</comments> <pubDate>Sun, 23 Jan 2011 03:17:46 +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[translate]]></category> <category><![CDATA[yii]]></category><guid
isPermaLink="false">http://www.larryullman.com/?p=2236</guid> <description><![CDATA[Mémorandom, which is translating my popular “Learning the Yii Framework” into French and publishing it online, has recently posted the translated versions of two more parts in the series. The fourth part is Defining Databases for the Yii Application. The fifth part is Creating Models, Views, and Controllers in Yii. My thanks again to Nico [...]]]></description> <content:encoded><![CDATA[<p><a
href="http://www.memorandom.fr/">Mémorandom</a>, which is translating my popular “<a
href="../series/learning-the-yii-framework/">Learning the Yii Framework</a>” into French and publishing it online, has recently posted the translated versions of two more parts in the series. The fourth part is <a
href="http://www.memorandom.fr/php/definir-une-base-de-donnees-pour-notre-application-yii/">Defining Databases for the Yii Application</a>. The fifth part is <a
href="http://www.memorandom.fr/php/creer-les-modeles-les-vues-et-les-controleurs-dans-yii/">Creating Models, Views, and Controllers in Yii</a>. My thanks again to Nico for the  nice words on my series and for the work in translating it!</p> ]]></content:encoded> <wfw:commentRss>http://www.larryullman.com/2011/01/23/more-of-learning-the-yii-framework-series-in-french/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> </channel> </rss>
<!-- Served from: www.larryullman.com @ 2012-05-21 15:11:27 by W3 Total Cache -->
