<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1870641221967095133</id><updated>2026-07-21T13:25:36.903-04:00</updated><category term="Yii"/><category term="Databases"/><category term="MySQL"/><category term="Tutorials"/><category term="Web Development"/><category term="CakePHP"/><category term="Git"/><category term="JQuery"/><category term="Debugging"/><category term="Game Theory"/><category term="JavaScript"/><category term="Miscellaneous"/><category term="Photoshop"/><category term="SEO"/><title type='text'>Yii / JQuery Web Development</title><subtitle type='html'>Random findings, gotchya&#39;s, and breakthroughs in my experiments with Yii and JQuery for Fireteams.net</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://brixican.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://brixican.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1870641221967095133.post-5695358870412444456</id><published>2012-07-11T18:23:00.001-04:00</published><updated>2012-07-11T18:26:03.828-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Debugging"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><category scheme="http://www.blogger.com/atom/ns#" term="JQuery"/><title type='text'>A JavaScript Instrumentation Technique for Easier Script Debugging</title><content type='html'>&lt;br /&gt;
There are many ways to debug your JavaScript code. My favorite way is to use console.log() to dump variables and print program state to the debugging console. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;

 The problem?&amp;nbsp;&lt;/h3&gt;
&lt;br /&gt;
If you&#39;ve ever created a relatively large JavaScript library or program, specifically with lots of functions, your debugging log can quickly become overwhelming. At work, I ended up creating a decent size JS library. I found that every time I had to debug a problem, I was spending most of my time parsing my own debug statements than I was fixing the problem.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;

 My Solution: Instrumentation!&lt;/h3&gt;
&lt;div&gt;
&lt;br /&gt;
Instrumentation can mean many things, so specifically I&#39;m referring to tracing the execution flow of your scripts through logging. Take the following JavaScript as an example:&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;function addRand()
{
    var r = Math.floor(Math.random()*11); // return randomly between 0 and 10
    console.log(&quot;addRand returning: &quot;, r);
    return r;
}

function mult(a, b)
{
    var m = a * b;
    return m;
}

function doStuff()
{
    var a=2, b=5;
    console.log(&quot;Multiplying A and B&quot;);
    var m = mult(a, b);
    console.log(&quot;Adding a random number to the result&quot;);
    m += addRand();        
    console.log(&quot;Result: &quot;, m);
}

doStuff();
&lt;/pre&gt;
&lt;br /&gt;
This code will produce the following (boring) log file:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;Multiplying A and B
Adding a random number to the result
addRand returning: 2
Result: 12
&lt;/pre&gt;
&lt;br /&gt;
Pretty sad, really. Firefox, Chrome, Safari, heck even Internet Explorer have now mostly adopted the Firebug way of debugging javascript. We can add a lot to our debugging by simply using two built-in functions, console.group() and console.groupEnd(). All they do is create (and remove) an indentation for any print statements between calls to each function. Together, they end up producing a very readable log. Here&#39;s the code with my Instrumentation added:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;function _Instrument(info)
{
    console.group(
        info.name + &quot; variables: &quot;, (info.variables ? info.variables : &quot;(void)&quot;)
    );
}

function _InstrumentEnd(info)
{
    console.log(&quot;Returning: &quot;, (info &amp;amp;&amp;amp; info.return ? info.return : &quot;(void)&quot;));
    console.groupEnd();
}

function addRand()
{
    _Instrument({name:&quot;addRand&quot;})
    var r = Math.floor(Math.random()*11); // return randomly between 0 and 10
    _InstrumentEnd({return: {randomNum: r}});
    return r;
}

function mult(a, b)
{
    _Instrument({name:&quot;mult&quot;, variables: {a:a, b:b}});
    var m = a * b;
   _InstrumentEnd({return: {m: m}});
    return m;
}

function doStuff()
{
    _Instrument({name: &quot;doStuff&quot;});
    var a=2, b=5;
    console.log(&quot;Multiplying A and B&quot;);
    var m = mult(a, b);
    console.log(&quot;Adding a random number to the result&quot;);
    m += addRand();        
    console.log(&quot;Result: &quot;, m);
    _InstrumentEnd();
}

doStuff();
&lt;/pre&gt;
&lt;br /&gt;
Sure, it may add a couple lines of code to each function, but it results in a log file with much more information. Put this into an environment with thousands of lines of debug information, and it becomes significantly more readable, and faster to parse.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRv0HCaAP54CCizq4NE-m-r-5GRWpQ5DqfxzU5CMR3V4KWnxB4xwHWHiAAeM_2XaH8plyX5U8eqS5BmxLcquGDo_5BsI5fClaGvKWtJVkxf7asv3atEnbtz3Tg4n8E6KP7HF2_qC0bc2LC/s1600/Instrumentation+in+JavaScript.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRv0HCaAP54CCizq4NE-m-r-5GRWpQ5DqfxzU5CMR3V4KWnxB4xwHWHiAAeM_2XaH8plyX5U8eqS5BmxLcquGDo_5BsI5fClaGvKWtJVkxf7asv3atEnbtz3Tg4n8E6KP7HF2_qC0bc2LC/s1600/Instrumentation+in+JavaScript.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
By printing to your log when you enter and exit each function, you can quickly pinpoint which function is responsible for errors. This method also helps you trace the execution path of your scripts, which can help reduce your time spent on debugging. This has reduced my debugging time, and made it a lot less annoying to parse my logs, double win!&lt;br /&gt;
&lt;br /&gt;
If you&#39;re interested in what other functions you may be able to use to enhance your debugging logs, check out&amp;nbsp;&lt;a href=&quot;http://getfirebug.com/logging/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Firebug&#39;s Logging API&lt;/a&gt;, as most of these functions are built-in to Firefox and Chrome.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brixican.blogspot.com/feeds/5695358870412444456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://brixican.blogspot.com/2012/07/javascript-instrumentation-technique.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/5695358870412444456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/5695358870412444456'/><link rel='alternate' type='text/html' href='http://brixican.blogspot.com/2012/07/javascript-instrumentation-technique.html' title='A JavaScript Instrumentation Technique for Easier Script Debugging'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRv0HCaAP54CCizq4NE-m-r-5GRWpQ5DqfxzU5CMR3V4KWnxB4xwHWHiAAeM_2XaH8plyX5U8eqS5BmxLcquGDo_5BsI5fClaGvKWtJVkxf7asv3atEnbtz3Tg4n8E6KP7HF2_qC0bc2LC/s72-c/Instrumentation+in+JavaScript.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1870641221967095133.post-2515479578673050450</id><published>2012-07-07T23:57:00.000-04:00</published><updated>2012-07-11T18:24:19.967-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Databases"/><category scheme="http://www.blogger.com/atom/ns#" term="Git"/><category scheme="http://www.blogger.com/atom/ns#" term="MySQL"/><category scheme="http://www.blogger.com/atom/ns#" term="Tutorials"/><category scheme="http://www.blogger.com/atom/ns#" term="Web Development"/><category scheme="http://www.blogger.com/atom/ns#" term="Yii"/><title type='text'>A Basic Guide for Newbie Yii Developers Part II</title><content type='html'>&lt;br /&gt;
This is Part II of my introduction to Yii tutorials. If you haven&#39;t yet, take a look at&amp;nbsp;&lt;a href=&quot;http://brixican.blogspot.com/2012/07/me-want-website-but-where-to-start.html&quot; target=&quot;_blank&quot;&gt;Basic Guide for Newbie Yii Developers Part I&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Last week I covered how to create your first Yii project and put it under version control. In that tutorial, we created the project files for our first app: Yiicommerce. If you have been following along, great! If not, you can find the project files &lt;a href=&quot;https://github.com/brixican/Yii-commerce&quot; target=&quot;_blank&quot;&gt;on Github&lt;/a&gt;. I have made a Git Tag representing the state of the project at the end of the last tutorial (don&#39;t worry, I&#39;ll show you how to do it too!), so download&amp;nbsp;&lt;a href=&quot;https://github.com/brixican/Yii-commerce/tags&quot; target=&quot;_blank&quot;&gt;Tutorial-Part.I&lt;/a&gt;&amp;nbsp;and follow along!&lt;br /&gt;
&lt;br /&gt;
If you&#39;re using Git, you can also checkout the tag like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ git clone git@github.com:brixican/Yii-commerce.git
$ git checkout tutorial-part.I
&lt;/pre&gt;
&lt;br /&gt;
In part II of this series, we will begin designing our e-commerce application, starting at the database level. Today we&#39;ll build our database schema in MySQL, and use Yii&#39;s built-in Gii component to generate our initial Models, Views and Controllers. Before we get started, I think a brief introduction into some core Yii elements are in order.&lt;br /&gt;
&lt;h2&gt;

 &lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;An Overview of the Yii Framework&lt;/span&gt;&lt;/h2&gt;
&lt;h3&gt;

 &lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Models, Views, Controllers, Oh My!&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;If you have already begun looking into using Yii, or any PHP framework, no doubt you&#39;ve been barraged by the term MVC. What is MVC? It&#39;s a design pattern. It&#39;s a best practice, if you will, for organizing your code and functionality. By separating core components of your application, such as the business logic, user interfaces, and the data, you (the developer) can focus on developing each component without worrying about breaking, or&amp;nbsp;interfering&amp;nbsp;with, the others. If you are absolutely new to the MVC design pattern, I would highly recommend taking a quick look at the official&amp;nbsp;&lt;a href=&quot;http://www.yiiframework.com/doc/guide/1.1/en/basics.mvc&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Yii MVC Fundamentals&lt;/a&gt;&amp;nbsp;tutorial, as they do a great job at explaining what MVC is and how it works. I will assume you have a basic grasp of the concept. Rather than explain MVC, I will explain where various portions of a website fit into these designs.&lt;/span&gt;&lt;/div&gt;
&lt;h3&gt;

&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3&gt;

&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Models&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Models are the core of your application. They contain your business logic. They also dictate how data is accessed and stored. Models can hold any and all information in a website. For&amp;nbsp;&lt;a href=&quot;http://www.piecesofeightcostumes.com/products&quot; target=&quot;_blank&quot;&gt;Pieces of Eight Costumes&lt;/a&gt;, models are used to represent each individual product in the site. My models store price information, product names and descriptions. They also store relational data, such as what sizes (small, medium, large, etc..) each product supports, the category a product falls under, and other important relations. Of course the models I am describing here store data in a database, but Yii also supports other types of models as well. Not all data handled by a website gets stored into a database. For example, a &quot;Contact Us&quot; form, that takes some user input and emails it somewhere does not necessarily need to store that information. Yii provides us with special models designed to temporarily store this data. It helps us organize, manipulate, and validate our input before deciding to either store it, email it, or display it.&lt;/span&gt;&lt;/div&gt;
&lt;h3&gt;

&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3&gt;

&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Views&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Views contain all of the logic to present your website to your audience. Not only will views be where you write your HTML, they will also be where you invoke CSS and Javascript, perform AJAX calls, render web forms, and create templates and layouts. Views also aid in gathering user input and passing it into a Model. For example, a contact form stores its data into a model, but gets passed into a view to be rendered. The same form can be rendered in a variety of ways simply using different views. In general you will have a view per section of your website, such as a &quot;Contact Us&quot; view, &quot;About Us&quot; view, a view for your home page. However many views are also very re-useable. For example for PiecesOfEightCostumes.com, each category uses the same view to render the data, we simply pass it different products to render. Also, the page to render a single product is a generic view that simply takes a Product model and renders it to the page. In Yii, views come with many very handy functions to help speed up the development of HTML.&lt;/span&gt;&lt;/div&gt;
&lt;h3&gt;

&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3&gt;

&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Controllers&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Controllers are essentially the glue of any application. They control the flow of the users experience: handing them to the different views on your website, passing data between views and models, and helping to select which business logic to invoke based on the current state of the application. Controllers are comprised of Actions. In the &#39;Contact Us&#39; example, our action would instantiate and initialize our ContactForm model and pass it to the Contact view. Yii also maps actions to URLs, so we could setup a url such as www.website.com/contact to begin the process of rendering the view.&lt;/span&gt;&lt;br /&gt;
&lt;h3&gt;

&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3&gt;

 &lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Yii Folder Structure&lt;/span&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Right now, the folder structure for Yii-Commerce looks like this:&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;yiicommerce/&lt;/span&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;assets/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;css/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;images/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;protected/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;themes/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;index-test.php&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;index.php&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;README.md&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;We&#39;ll eventually explain the purpose of most of the files, but in this tutorial we are going to focus on the contents of protected/, as that is where the majority of the Yii-Commerce project files are:&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;yiicommerce/protected/&lt;/span&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;commands/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;components/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;config/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;controllers/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;data/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;extension/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;messages/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;migrations/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;models/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;runtime/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;tests/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;views/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;.htaccess&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;The amount of folders may seem a bit overwhelming at first, but don&#39;t worry! They are purely for organizational purposes. For example, all of our application&#39;s Models will be placed in the models/ directory. If you begin exploring these folders, you&#39;ll see our application already has some models an controllers and such. That&#39;s because the app we generated is already functional! We&#39;ll be deleting and editing files we don&#39;t need, so for now you can ignore the additional functionality in the application.&lt;/span&gt;&lt;br /&gt;
&lt;h2&gt;

 &lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Designing our Database Schema&lt;/span&gt;&lt;/h2&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Finally we get to the coding! In my opinion, the best place to start designing an application for Yii is with the database.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Being an e-commerce application, our number one concern is selling products. We need a way to represent a product in our database. Let&#39;s start off by making Products and Categories. We want products that have a name, price, and description. Each Product will belong to exactly one Category, and each Category can contain multiple products.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;In your &lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;protected/data/&lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&amp;nbsp;folder, create a file called &lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;yiicommerce.schema.sql&lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&amp;nbsp;with the following contents:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:sql&quot;&gt;#-- Category : represents a Category in the database
#-- Category HasMany Product
CREATE TABLE yc_category
(
 #-- Key
 id  INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
 
 #-- Attributes
 name  VARCHAR(255) NOT NULL,
 
 #-- Constraints
 PRIMARY KEY (id),
 UNIQUE KEY fk_category_name(name)
 
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


#-- Product : a product to sell in our application
#-- Product BelongsTo Category
CREATE TABLE yc_product
(
    #-- Key
    id            INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,

    #-- Attributes
    name          VARCHAR(40) NOT NULL,
    price         DECIMAL(6, 2) NOT NULL,
    description   TEXT,
    
    #-- Relationships
    category_id   INTEGER UNSIGNED NOT NULL,

    #-- Constraints
    PRIMARY KEY (id),
    FOREIGN KEY (category_id) REFERENCES yc_category(id),
    UNIQUE KEY uk_product_name (name)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

#--
#-- Test Data
#--
INSERT INTO category (name)
VALUES
 (&quot;Electronics&quot;),
 (&quot;Clothes&quot;),
 (&quot;Sporting Goods&quot;);

INSERT INTO yc_product (id, name, price, description, category_id)
VALUES
 (1, &quot;Laptop&quot;, 1200.00, &quot;A stunning little laptop.&quot;, 1),
 (2, &quot;Smartphone&quot;, 299.99, &quot;The most powerful smartphone yet.&quot;, 1),
 (3, &quot;White Shirt&quot;, 12.50, &quot;Comfortable, cotton, and plain.&quot;, 2),
 (4, &quot;Football Helmet&quot;, 68.75, &quot;Authentic NFL helmet.&quot;, 3);
&lt;/pre&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Here, we have created the schema for our products. A product has Name, Price, and Description attributes. It uses an integer as the Primary Key inside of the database, and as a further constraint, no two products can have the same name. We also link Products and Categories together using the category_id attribute. By linking in this way, our Category models can each contain many Products, but our Product models can only belong to exactly one Category. We also created a few test categories and products, which we can always alter later.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Now that we&#39;ve created the schema, it&#39;s time to make our tables. If you&#39;re using XAMPP or something similar, you probably already have phpMyAdmin installed. Go to &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;http://localhost/phpmyadmin&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;, and create a new database called &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;yiicommerce&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;. Once created, click the SQL tab, then copy and paste the contents of your schema file and hit the Go button. You will now see two tables, &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;yc_category&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt; and &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;yc_product&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Now we need to configure Yii to communicate with our database. Open the config file located at: &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;/protected/config/main.php&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;. Locate the &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&#39;components&#39;&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&amp;nbsp;key, and under that the &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&#39;db&#39; &lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;key. You&#39;ll notice there are two entries, an sqlite string and a commented-out mysql string. Since we&#39;re not using sqlite, delete that one and uncomment the mysql string. In the &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&#39;connectionString&#39;&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;, replace&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&#39;mysql:host=localhost;dbname=testdrive&#39;&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&amp;nbsp;with&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&#39;mysql:host=localhost;dbname=yiicommerce&#39;&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;, and fill in your username and password to your database if necessary. Yii now has access to our database.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;h3&gt;

&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3&gt;

&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Gii&amp;nbsp;&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;We&#39;re going to use Yii&#39;s built-in component called &quot;Gii&quot; to take our database schema, and generate our models, views, and controllers for us. While this is not a feature unique to Yii (Ruby on Rails, Symfony, CakePHP, etc.. all have a similar tool), it is nevertheless a very powerful tool that Yii provides us.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;In the config file, scroll up to the&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&#39;modules&#39;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;key, and uncomment the Gii tool, as we will be using this next. Change the password to something simple, and remember to remove this section before ever deploying your Yii application.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Visit the following URL to login to the Gii tool (using the password in your config file): &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;http://localhost/yiicommerce/index.php?r=gii&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;, then click on the &#39;Model Generator&#39; link.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;For the Table Prefix, put in the &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&#39;yc_&#39;&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&amp;nbsp;prefix that we added to all of our table names. Insert &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&#39;*&#39;&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&amp;nbsp;under Table Name to have Gii generate all of our tables at once. Finally, click the preview button, and then the generate button. If Yii has an error writing the files, make sure your directories are writeable using the following chmod command:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ chmod -R 766 protected/
&lt;/pre&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Now that Yii has now created our models, let&#39;s make a controller and a view for it. Click the &#39;Controller Generator&#39; link, and enter &#39;product&#39; for the controller id field. We&#39;ll leave the Action IDs with just index for now. Again, click preview and generate to create our controller and view file.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;We now have the following files created in our &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;protected/&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt; folder:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;models/Product.php&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;models/Category.php&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;controllers/ProductController.php&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;views/product/index.php&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;We can view our newly created content (although there&#39;s not much to see) by going to the following URL: &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;http://localhost/yiicommerce/index.php?r=product&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3&gt;

&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3&gt;

 &lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Committing our Changes&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Now that we have altered our application, it&#39;s time to save our changes. The following Git commands will add our files into our repository, and commit changes to existing files:&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ git add -A
$ git commit -a -m &quot;Added Product and Category models. Created controller and view for Products&quot;
$ git push origin master
&lt;/pre&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;After entering your password, your changes will now be commited into your github repository. You&#39;ll notice I&#39;ve been creating Tags for each tutorial. A Tag is essentially a snapshot of the project files. To create the Tag for this tutorial, I ran the following commands:&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ git tag -a tutorial-part.II -m &quot;Tutorial Part II&quot;
$ git push --tags origin master
&lt;/pre&gt;
&lt;span style=&quot;background-color: white; font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;While tags are not something you will create often, they work very well for tagging release versions of software.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Anyway, that&#39;s it for today! Next time we&#39;ll spruce up those controllers and views and start making some useful web functionality!&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://brixican.blogspot.com/feeds/2515479578673050450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://brixican.blogspot.com/2012/07/basic-guide-for-newbie-yii-developers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/2515479578673050450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/2515479578673050450'/><link rel='alternate' type='text/html' href='http://brixican.blogspot.com/2012/07/basic-guide-for-newbie-yii-developers.html' title='A Basic Guide for Newbie Yii Developers Part II'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1870641221967095133.post-5176327880118711637</id><published>2012-07-04T19:45:00.003-04:00</published><updated>2012-07-08T00:18:42.366-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Git"/><category scheme="http://www.blogger.com/atom/ns#" term="Tutorials"/><category scheme="http://www.blogger.com/atom/ns#" term="Web Development"/><category scheme="http://www.blogger.com/atom/ns#" term="Yii"/><title type='text'>Me want website, but where to start? A basic guide for newbie Yii Developers - Part I</title><content type='html'>&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Welcome to my Yii developer tutorial series! These tutorials are aimed at taking absolutely new Yii developers through the process of developing their first website. Instead of creating a boring Blog application, I am going to walk through the process of creating a (very basic) E-Commerce site. I&#39;ll go into more details about what we will be building in the next post. In the first installment of my set of Yii tutorials, I&#39;m going to show how to:&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Download and test Yii&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Creating our first project&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: white; font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Git-ing started with version control&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;First, an introduction is in order. Who the hell am I, and where do I get off teaching you how to code? My name is AJ Perez. I do computer security for a living and web / game development as a hobby. I have been using Yii for the past couple of years and have been developing with PHP ever since I started programming. I received my degree in Computer Science from Oregon State University in 2010. I tend to dabble in many things, and always have multiple projects going on outside of work, but web development is still my favorite hobby.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Whew, got that out of the way. My goal here is to get new developers moving in the right direction. I don&#39;t claim that what I will show you, nor how I develop it, are necessarily the best practices for Yii. If it gets you hitting the ground running and producing results than I will consider my job done.&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;b&gt;Disclaimer:&lt;/b&gt; if you are new to Yii and reading this, I am just as new to writing tutorials as you are to the framework, so positive (and negative!) feedback is welcomed and encouraged.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;These posts will be an ongoing set of tutorials, building upon the same project throughout each tutorial until we end up with a basic, but finished, website. Due to content length, I may end up splitting some tutorials amongst multiple posts, but I&#39;ll be sure to link them appropriately. I will also have my version of the code on github, so people can download it and see the code first hand, but I encourage people to do these tutorials alongside me, as nothing beats learning by doing it yourself. Finally, enough blabbing, let&#39;s get started shall we?&lt;/span&gt;&lt;br /&gt;
&lt;h2&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Downloading Yii&lt;/span&gt;&lt;/h2&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;If you haven&#39;t already, go ahead and&amp;nbsp;&lt;a href=&quot;http://www.yiiframework.com/download/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Download Yii&lt;/a&gt;&amp;nbsp;from their website. At the time of this writing, Yii 1.1.10 is the latest version so that is what I will be using. Once downloaded, unzip the folder from the archive and place it into your webroot (I renamed the folder from the default yii-1.1.10.r3566 to simply &quot;yii&quot;. I&#39;ll assume you already have a local development environment established (but if not, I would recommend&amp;nbsp;&lt;a href=&quot;http://www.apachefriends.org/en/xampp.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;XAMPP&lt;/a&gt;&amp;nbsp;for OSX or Windows). I use OSX for my web development, so my tutorials will be done in that environment, but absolutely all of the tasks I do will carry over to a Windows (and especially Linux) environment, albeit a few minor differences at times.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;The folder we now have contains the following folder structure:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;demos/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;framework/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;requirements/&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;We&#39;ll leave the demos folder for now, since they can be useful in seeing various ways to build projects. In your web browser, visit the following url: &quot;&lt;span style=&quot;background-color: white;&quot;&gt;http://localhost/yii/requirements/&quot;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Before moving on, fix any errors marked as &quot;Failure&quot;. If your tests look similar to mine then you have successfully installed Yii, congratulations!&lt;/span&gt;&lt;/div&gt;&lt;h2&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;The First Project&lt;/span&gt;&lt;/h2&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Alright, we finally gave our Yii framework a nice little home in our webroot, now it&#39;s time to setup the project files for our first Yii application. We&#39;re going to use Yii&#39;s built-in &quot;YiiC&quot; app to auto-generate our project files for us. I decided to name our application &quot;YiiCommerce,&quot; I know, I&#39;m so creative. The following process is highly documented, so if you get lost following me, try Yii&#39;s documentation for&amp;nbsp;&lt;a href=&quot;http://www.yiiframework.com/doc/guide/1.1/en/quickstart.first-app&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Creating your First Yii Application&lt;/a&gt;.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;1) In a command-line terminal, navigate to your webroot:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;pre class=&quot;brush:bash&quot;&gt;$ cd /Applications/XAMPP/htdocs/
&lt;/pre&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;2) We should now see our &quot;yii/&quot; folder. Run the following command to generate our project files:&lt;/span&gt;&lt;/div&gt;&lt;pre class=&quot;brush:bash&quot;&gt;$ php yii/framework/yiic.php webapp yiicommerce
&lt;/pre&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;* If your console complains about not being able to find your php executable, just use the full path instead:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;/usr/bin/php&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt; in Linux,&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;/Applications/XAMPP/xamppfiles/bin/php&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt; in OSX&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;3) We should now see the following folders in our webroot:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;yii/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;yiicommerce/&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;To test it out, visit the following URL:&amp;nbsp;&lt;span style=&quot;background-color: white;&quot;&gt;http://localhost/yiicommerce/index.php&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;If you see a welcome message, then congratulations, we have our first Yii application running! We&#39;ll start the process of making it all fancy in the next tutorial.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h2&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Git-R-Done!&lt;/span&gt;&lt;/h2&gt;&lt;h3&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Setting up our Git Repository&lt;/span&gt;&lt;/h3&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Now that we have our project files ready, it&#39;s time to add them into a Git Repo. If you&#39;re new to Git, I&#39;ll attempt to explain the Git commands as I use them. There&#39;s a great&amp;nbsp;&lt;a href=&quot;http://www.vogella.com/articles/Git/article.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Git Tutorial&lt;/a&gt;&amp;nbsp;here that I often refer back to, if I forget a particular command. I&#39;m not going to attempt to walk you through the process of installing and setting up Git, since their creators did such a good job walking you through the process already. So, follow&amp;nbsp;&lt;a href=&quot;https://help.github.com/articles/set-up-git&quot; target=&quot;_blank&quot;&gt;their Github guide&lt;/a&gt;&amp;nbsp;to set it up.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Once Git is installed and configured, we can create our repository. Create a new public repository (on github), I called mine &quot;Yii-Commerce,&quot; and you can&amp;nbsp;&lt;a href=&quot;https://github.com/brixican/Yii-commerce&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;view it here&lt;/a&gt;. Since we&#39;re using github, you&#39;ll notice a button that&#39;s called &quot;Gitignore&quot;, scroll down its list and click &#39;Yii&#39;. &amp;nbsp;Github is nice enough to have bunches of presets for many types of projects that will automatically ignore files that shouldn&#39;t be included in your repository. In case you didn&#39;t see it, don&#39;t worry, i&#39;ll walk through the process of setting up our .gitignore file later.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Now that you have your repository, we need to add our project files to it! In your command line, change the working directory to your newly-created project:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ cd webroot/yiicommerce/
&lt;/pre&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Now run the following command to create and initialize an empty local repository:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ git init
&lt;/pre&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Next, add all of the files from your project into the Git repo:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ git add .
$ git commit -m &quot;First Commit&quot;
&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Here, we have added all of the files from our project into our Git repository.&amp;nbsp;Committing&amp;nbsp;the changes to the repo finalize the adding process. Git will make sure you always add a message for each commit, so make sure you choose meaningful messages such as: &quot;Edited the product model - now includes pricing and descriptions for each model.&quot; Meaningful messages will help you track your changes more accurately.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;The next step is to push our local repository to github. On your github page, you should see your .git url, mine is:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;https://github.com/brixican/Yii-commerce.git&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;This is the address to your remote repository on github. To connect it to our local repo, use the following command:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ git remote add origin https://github.com/brixican/Yii-commerce.git
&lt;/pre&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Replacing my URL for yours, of course. Lastly, we can push our local repository over to our remote one:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ git pull origin master
$ git push origin master
&lt;/pre&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;If your Git installation was anything like mine, it complained about SSH keys! If it worked, you can skip these steps.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;To setup your SSH Keys, follow Git&#39;s&amp;nbsp;&lt;a href=&quot;https://help.github.com/articles/generating-ssh-keys&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;generating ssh keys&lt;/a&gt;&amp;nbsp;tutorial. If this doesn&#39;t work (again, like my git installation), then we&#39;ll switch from using the HTTPS git server to the SSH-based one. Run the following two commands to switch your repo:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ git remote rm origin
$ git remote add origin git@github.com:brixican/Yii-commerce.git
&lt;/pre&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Now we should be good to go, we&#39;ll try to merge and push our repos again:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ git pull origin master
$ git push origin master
&lt;/pre&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;...and it finally worked! Hopefully you won&#39;t have as many problems as I had setting up a git repo, but if you did hopefully my suggestions helped you get it going. You can verify that the repository has been uploaded successfully by refreshing your project page on github. If you can see your project files, then all is well. Now we finally have our first Yii project safely saved into Git.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Keep an eye posted for my next post, where we&#39;ll start adding some of our business logic into our application. Finally, some real coding! If I have any errors, or you have any problems or suggestions, let us hear about them in the comments!&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;See you next week!&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
Edit:&amp;nbsp;&lt;a href=&quot;http://brixican.blogspot.com/2012/07/basic-guide-for-newbie-yii-developers.html&quot; target=&quot;_blank&quot;&gt;Part II&lt;/a&gt;&amp;nbsp;of this series is now up!&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brixican.blogspot.com/feeds/5176327880118711637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://brixican.blogspot.com/2012/07/me-want-website-but-where-to-start.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/5176327880118711637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/5176327880118711637'/><link rel='alternate' type='text/html' href='http://brixican.blogspot.com/2012/07/me-want-website-but-where-to-start.html' title='Me want website, but where to start? A basic guide for newbie Yii Developers - Part I'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1870641221967095133.post-1524548834682071117</id><published>2012-06-13T10:26:00.000-04:00</published><updated>2012-07-05T08:06:26.143-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SEO"/><category scheme="http://www.blogger.com/atom/ns#" term="Tutorials"/><category scheme="http://www.blogger.com/atom/ns#" term="Web Development"/><category scheme="http://www.blogger.com/atom/ns#" term="Yii"/><title type='text'>Yii Development Tutorials</title><content type='html'>&lt;span style=&quot;font-family: &#39;Helvetica Neue&#39;, Arial, Helvetica, sans-serif;&quot;&gt;Well, it&#39;s been a while since I have written any blogs. Development on Fireteams has stopped for the time being as well. Unfortunately I have just had too many things happening at once. &amp;nbsp;On the plus side, I just finished an e-commerce website for a client (check it out!&amp;nbsp;&lt;a href=&quot;http://www.piecesofeightcostumes.com/&quot; target=&quot;_blank&quot;&gt;Pieces of Eight Costumes&lt;/a&gt;). I used Yii to make this website for them, and I&#39;ll be posting some tutorials about how to use Yii to implement various parts of an e-commerce site! Here&#39;s a look at what to expect in the coming months (not necessarily in this order):&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &#39;Helvetica Neue&#39;, Arial, Helvetica, sans-serif;&quot;&gt;&lt;a href=&quot;http://brixican.blogspot.com/2012/07/me-want-website-but-where-to-start.html&quot; target=&quot;_blank&quot;&gt;Me want website, but where to start? A basic guide for newbie Yii developers&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &#39;Helvetica Neue&#39;, Arial, Helvetica, sans-serif;&quot;&gt;So I heard you like E-commerce.. (How to start developing your e-commerce site using Yii)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &#39;Helvetica Neue&#39;, Arial, Helvetica, sans-serif;&quot;&gt;Developing a basic cart with PayPal integration with Yii&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &#39;Helvetica Neue&#39;, Arial, Helvetica, sans-serif;&quot;&gt;Creating a complex AJAX form with Yii and JQuery&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &#39;Helvetica Neue&#39;, Arial, Helvetica, sans-serif;&quot;&gt;Yii + Google == &lt;span style=&quot;background-color: white; text-align: -webkit-left;&quot;&gt;&lt;span style=&quot;color: #333333; font-style: italic; text-align: -webkit-auto;&quot;&gt;♥&lt;/span&gt;&amp;nbsp;&lt;/span&gt;— Good SEO practices for any website&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &#39;Helvetica Neue&#39;, Arial, Helvetica, sans-serif;&quot;&gt;How to deploy a Yii website on HostGator&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &#39;Helvetica Neue&#39;, Arial, Helvetica, sans-serif;&quot;&gt;My favorite Yii / JQuery plugins of 2012&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Helvetica Neue&#39;, Arial, Helvetica, sans-serif;&quot;&gt;There&#39;ll be additional tutorials as well, but I will most definitely be writing these articles in the months ahead. Hopefully developers still rather new to Yii will find these tutorials useful and get a good feel for how powerful the framework is.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Helvetica Neue&#39;, Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Helvetica Neue&#39;, Arial, Helvetica, sans-serif;&quot;&gt;If you have any tutorial requests, or would like to share links to other great tutorials out there, let us know in the comments!&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brixican.blogspot.com/feeds/1524548834682071117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://brixican.blogspot.com/2012/06/yii-development-tutorials.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/1524548834682071117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/1524548834682071117'/><link rel='alternate' type='text/html' href='http://brixican.blogspot.com/2012/06/yii-development-tutorials.html' title='Yii Development Tutorials'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1870641221967095133.post-6211013167243929634</id><published>2011-06-19T16:49:00.000-04:00</published><updated>2011-06-19T16:49:06.781-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Databases"/><category scheme="http://www.blogger.com/atom/ns#" term="MySQL"/><title type='text'>MySQL Comparing NULL values returns empty set</title><content type='html'>It has been a little while since I touched some MySQL. Long enough that I forgot about an issue with how MySQL treats NULL values. &amp;nbsp;What&#39;s the issue? You cannot use the typical SQL comparison operators when testing for a NULL value. &amp;nbsp;It even says so in the MySQL documentation:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/problems-with-null.html&quot;&gt;http://dev.mysql.com/doc/refman/5.0/en/problems-with-null.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
It states two facts:&lt;br /&gt;
&amp;nbsp; * &quot;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #555555; font-family: helvetica, arial, sans-serif; font-size: 14px; line-height: 25px;&quot;&gt;In SQL, the&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #555555; font-family: helvetica, arial, sans-serif; font-size: 14px; line-height: 25px;&quot;&gt;&lt;code class=&quot;literal&quot; style=&quot;background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #026789; font-family: &#39;courier new&#39;, courier, fixed, monospace; font-size: 13px; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;&quot;&gt;NULL&lt;/code&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #555555; font-family: helvetica, arial, sans-serif; font-size: 14px; line-height: 25px;&quot;&gt;&amp;nbsp;value is never true in comparison to any other value, even&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #555555; font-family: helvetica, arial, sans-serif; font-size: 14px; line-height: 25px;&quot;&gt;&lt;code class=&quot;literal&quot; style=&quot;background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #026789; font-family: &#39;courier new&#39;, courier, fixed, monospace; font-size: 13px; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;&quot;&gt;NULL.&quot;&lt;/code&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #555555; font-family: helvetica, arial, sans-serif; font-size: 14px; line-height: 25px;&quot;&gt;&lt;code class=&quot;literal&quot; style=&quot;background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #026789; font-family: &#39;courier new&#39;, courier, fixed, monospace; font-size: 13px; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;&quot;&gt;&amp;nbsp;&lt;/code&gt;&lt;/span&gt;* &quot;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #555555; font-family: helvetica, arial, sans-serif; font-size: 14px; line-height: 25px;&quot;&gt;To look for&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #555555; font-family: helvetica, arial, sans-serif; font-size: 14px; line-height: 25px;&quot;&gt;&lt;code class=&quot;literal&quot; style=&quot;background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #026789; font-family: &#39;courier new&#39;, courier, fixed, monospace; font-size: 13px; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;&quot;&gt;NULL&lt;/code&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #555555; font-family: helvetica, arial, sans-serif; font-size: 14px; line-height: 25px;&quot;&gt;&amp;nbsp;values, you must use the&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #555555; font-family: helvetica, arial, sans-serif; font-size: 14px; line-height: 25px;&quot;&gt;&lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_is-null&quot; style=&quot;background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #00759f; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: underline; vertical-align: baseline;&quot;&gt;&lt;code class=&quot;literal&quot; style=&quot;background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #026789; font-family: &#39;courier new&#39;, courier, fixed, monospace; font-size: 13px; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: underline; vertical-align: baseline;&quot;&gt;IS NULL&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #555555; font-family: helvetica, arial, sans-serif; font-size: 14px; line-height: 25px;&quot;&gt;&amp;nbsp;test.&quot;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #026789; font-family: &#39;courier new&#39;, courier, fixed, monospace; font-size: 13px; font-weight: bold; line-height: 25px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #026789; font-family: &#39;courier new&#39;, courier, fixed, monospace; font-size: 13px; font-weight: bold; line-height: 25px;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
In other words, MySql provides special operators when dealing with NULL values. &amp;nbsp;So if you were trying to perform a simple query like this:&lt;br /&gt;
&lt;br /&gt;
SELECT id FROM users WHERE email = NULL&lt;br /&gt;
&lt;br /&gt;
you would not get a syntax error. Instead, you just get an empty result returned by the query. Thanks, MySQL. (I sadly spent a good couple of hours tracking this exact problem). &amp;nbsp;Instead, performing the query like this:&lt;br /&gt;
&lt;br /&gt;
SELECT id FROM users WHERE email IS NULL&lt;br /&gt;
&lt;br /&gt;
will yield the expected results. &amp;nbsp;There is also IS NOT NULL, and a function IFNULL() to aid in your NULL comparisons. &amp;nbsp;The documentation is a pretty good read, as mysql handles null quite differently then other languages. &lt;br /&gt;
&lt;br /&gt;
Hopefully this will help save some innocent keyboards being destroyed out of frustration!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #026789; font-family: &#39;courier new&#39;, courier, fixed, monospace; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 25px;&quot;&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://brixican.blogspot.com/feeds/6211013167243929634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://brixican.blogspot.com/2011/06/mysql-comparing-null-values-returns.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/6211013167243929634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/6211013167243929634'/><link rel='alternate' type='text/html' href='http://brixican.blogspot.com/2011/06/mysql-comparing-null-values-returns.html' title='MySQL Comparing NULL values returns empty set'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1870641221967095133.post-1544196120586535138</id><published>2011-04-22T16:19:00.000-04:00</published><updated>2011-04-22T16:19:49.695-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Databases"/><category scheme="http://www.blogger.com/atom/ns#" term="MySQL"/><title type='text'>5 MySQL Best Practices When Designing Schemas</title><content type='html'>&lt;div style=&quot;margin: 0px;&quot;&gt;As a follow up to my previous article on&amp;nbsp;&lt;a href=&quot;http://brixican.blogspot.com/2011/04/mysql-database-performance.html&quot;&gt;Common MySQL Performance Optimizations&lt;/a&gt;, I decided to post some of my research findings of MySQL best practices that are commonly suggested by MySQL experts in the community.&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;Following a set of established good practices can usually prevent common mistakes/errors or performances losses. Admittedly, some MySQL &#39;best practices&#39; can be elusive, so it is nice to see a few all in one place. Here is a list of practices I try to stick to when creating database schemas:&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;b&gt;1) Always specify NOT NULL if possible&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;For any field that does not need to hold a NULL value (usually most if not all of my fields in a table), specifically define that field as &#39;NOT NULL&#39;. Each table that does not specify this will actually be one byte larger than it should be. If you had a table with five INTEGER fields, none of which specify NOT NULL, than you are looking at:&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;5 fields X (4-byte INTEGER size + 1-byte NULL option) == 25 bytes per record.&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;If you specified NOT NULL:&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;5 fields X 4-byte INTEGER size == 20 bytes per record.&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;That&#39;s a 20% decrease in record size! This can cause huge performance gains when you&#39;re talking potentially hundreds of thousands of records.&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;b&gt;2) Specify the correct field types for the data you are storing.&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;If you have a field that will hold values between 1 and 10, don&#39;t specify that field as BIGINT (or even INT, for that matter). Store it in a TINYINT instead.&amp;nbsp; A Tinyint field can store values between -128 and 127 (0 and 256 if Unsigned), and is only 1-byte in size (as opposed to 4-byte Integer or 8-byte Bigint). If you are storing an IP address, consider using PHP (or your favorite language) to convert it to an integer, and store it in an INT type rather than a VARCHAR. If you know your username&#39;s or passwords cannot be longer than 40 characters, don&#39;t store them in a CHAR(256). Also, if you have a field that may store different string values such as this:&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;player_type &amp;nbsp; &amp;nbsp; &amp;nbsp;VARCHAR(32); &amp;nbsp; -- can be: &#39;Admin&#39;, &#39;Standard&#39;&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;consider instead making player_type an ENUM value. &amp;nbsp;The nice thing about enum values is that you can still interface with the variable using strings, but the actual values are stored as Ints!&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;player_type &amp;nbsp; &amp;nbsp; &amp;nbsp;ENUM(&#39;Admin&#39;, &#39;Standard&#39;); &amp;nbsp; -- Yay!&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;For more information on MySQL data types, check out the&amp;nbsp;&lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/data-types.html&quot;&gt;official documentation&lt;/a&gt;.&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;b&gt;3) &amp;nbsp;Always used UNSIGNED when possible&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;If you have integer fields in your tables which cannot or should not contain negative values, store them as UNSIGNED. &amp;nbsp;Not only will this double the amount of values that can be held in the variable, but it also ensures data integrity be not allowing the field to contain erroneous values.&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;b&gt;4) Use Indexes to your advantage&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;Properly defined indexes can be one of the biggest optimizations you can apply to your database. &amp;nbsp;When used incorrectly however, it can actually decrease performance. &amp;nbsp;The hardest thing about indexes is knowing when to use them, and when not to use them. &amp;nbsp;In general I think a good rule of thumb is if you are using a field in a WHERE clause, apply an index to it. &amp;nbsp;Doing so will help speed up searches, especially when performing joins. As always, be sure to utilize the EXPLAIN and SHOW aspects of MySQL in order to fully optimize your tables based on the queries used in your applications.&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;b&gt;5) Use LIMIT 1 when grabbing unique rows from a table&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;While this does not actually fit into the design stage of a schema, it was still a MySQL best practice that I learned while researching the topic. &amp;nbsp;Using LIMIT 1 ensures that once your unique row is found, MySQL will stop searching and return the results. &amp;nbsp;This can potentially provide a small performance boost to your applications.&amp;nbsp;&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;There are certainly more established best-practices touted by other MySQL experts in the community, and this is not an exhaustive list by far. &amp;nbsp;These were simply some of my favorites that I try to stick to whenever I am creating a new schema. &amp;nbsp;If you know of other best practices that should be followed when using MySQL, let us know about it in the comments!&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brixican.blogspot.com/feeds/1544196120586535138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://brixican.blogspot.com/2011/04/5-mysql-best-practices-when-designing.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/1544196120586535138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/1544196120586535138'/><link rel='alternate' type='text/html' href='http://brixican.blogspot.com/2011/04/5-mysql-best-practices-when-designing.html' title='5 MySQL Best Practices When Designing Schemas'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1870641221967095133.post-5649938615827568579</id><published>2011-04-19T01:44:00.006-04:00</published><updated>2011-04-19T01:53:05.554-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Databases"/><category scheme="http://www.blogger.com/atom/ns#" term="MySQL"/><title type='text'>Common MySQL Database Performance Optimizations</title><content type='html'>&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;While developing the database schema used by&amp;nbsp;&lt;a href=&quot;http://www.fireteams.net/&quot;&gt;Fireteams.net&lt;/a&gt;, I realized there were many performance improvements I could make upon my initial design. &amp;nbsp;After some research, I found that some of the performance boosts I applied were commonly asked questions on the internet. During this research I also learned some new tricks that I thought were very useful. While not a comprehensive list, I thought I would share some common performance optimizations and MySQL best practices that are commonly recommended amongst the MySQL community:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1) Normalize those Tables&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
It is highly recommended that you start your database designs in (at least) 3rd normal form. If you are unfamiliar with database normalization, the MySQL developer zone has a great&amp;nbsp;&lt;a href=&quot;http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html&quot;&gt;introductory article&lt;/a&gt;&amp;nbsp;on the subject. In general, normalizing your database involves creating tables such that every non-key element in the table is dependent upon a primary key, and only that key. Doing so increases data integrity by removing large amounts of data redundancy and (in my opinion) makes your database much easier to maintain. Normalization makes for a great starting point into further performance enhancements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2) Choose the right database Engine.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In MySQL, the choice generally boils down to MyISAM vs. InnoDB. &amp;nbsp;While a google search here can give you more information than I can about these choices, I will point out some interesting information about the two. &amp;nbsp;First, is that MyISAM does not support the use of Foreign Keys. &amp;nbsp;Foreign keys can be very important for data integrity, so anyone wishing to use this functionality will most likely want to use InnoDB as their storage engine. &amp;nbsp;InnoDB also supports the use of&amp;nbsp;&lt;a href=&quot;http://www.devshed.com/c/a/MySQL/Using-Transactions-In-MySQL-Part-1/&quot;&gt;Transactions&lt;/a&gt;, another invaluable tool for data integrity (and once again, something MyISAM tables do not support).&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
Something I learned recently about InnoDB regards its performance when counting rows in a table. &amp;nbsp;Basically, little metadata is kept about a table. If you wanted to count all rows in a table like this:&lt;br /&gt;
&lt;br /&gt;
SELECT COUNT(*) from Users;&lt;br /&gt;
&lt;br /&gt;
You will always end up iterating through each row in the table. This can cause a huge performance hit if you are running this query often on a table with hundreds of thousands of rows. &amp;nbsp;MyISAM tables do not have this problem, as the number of rows in the table is kept as metadata and is used directly by MySQL when calculating this value. Work around? Well, the generally accepted way is to create a separate table which stores the row counts. Of course this requires manually keeping a count of the rows, but if you need this data often then it may very well be worth the effort.&lt;br /&gt;
&lt;br /&gt;
Another note about MyISAM is that it is geared towards tables that are heavy on reads, with very little writes. If you have a table with a high number of updates or inserts vs the amount of selects, you will most likely have better performance using InnoDB instead. &amp;nbsp;For a great reference on the different types of storage engines, check out&amp;nbsp;&lt;a href=&quot;http://www.nileshpawar.com/mysqlexpert/2008/09/mysql-storage-engines/&quot;&gt;Nilesh Pawar&#39;s blog entry on MySQL Storage Engines&lt;/a&gt;. He also has a bunch of other great articles as well.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3) Vertical Partitioning&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
The concepts of vertical partitioning were new to me. After some poking around however, it turns out that when done correctly it can lead to a substantial performance boost. &amp;nbsp;The concept is simple: split a large table such that some of its columns exist in one table, and the rest of its columns exist in another table. Initially I thought it seemed rather pointless. You would still need to join the data back together, so wouldn&#39;t it simply hurt performance? Not when done correctly... Consider the following example table:&lt;br /&gt;
&lt;br /&gt;
Table User (&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;user_id,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;username,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;password,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;email,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;alternate_email,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;date_registered,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;subscribed_to_newsletter&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
The types of these fields are not important (hence them being omitted in this table). What can we note about this table? First is that every time a user logs in, the username, password, and maybe email fields will be touched. The other fields will most likely only be touched in specific portions of the application. When MySQL is searching/reading/writing records, the entire record must be brought into memory. The larger the record (the more fields in the table), the longer is operation can take. In other words, if this table was smaller we might increase the performance of accessing common User fields. If the tables were split &quot;Vertically&quot; like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Table User (&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;user_id,&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;username,&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;password,&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;email&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;);&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Table User_Profile (&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;user_id,&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;alternate_email,&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;date_registered,&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;subscribed_to_newsletter&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;);&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Accessing username and password become much faster, since it no longer has to load each of the other fields into memory just to access them. When date_registered or alternate_email are required, a simple join would re-create the full table. For more information about how vertical partitioning can increase performance, I found&amp;nbsp;&lt;a href=&quot;http://apheliondynamics.com/blog/2010/02/11/database-optimization-vertical-partitioning-in-mysql/&quot;&gt;this article&lt;/a&gt;&amp;nbsp;to be quite helpful.&lt;br /&gt;
&lt;br /&gt;
So, Vertical partitioning. You love it. You want to use it. How do you know which fields to split into another table? &amp;nbsp;There are many ways you can split a table, and it depends on the goals of your performance boost. Here are some common ways you could think about splitting your tables:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A) Split your read-heavy data from write-heavy data.&lt;br /&gt;
&lt;br /&gt;
When you have to write to a table, on top of access times you also may invalidate the record in the cache, which means slower access times when you want to read it again. By splitting read-heavy from write-heavy data into separate tables, your read-heavy data will stay in the cache, and both sets of data will also benefit from quicker access times (due to each table being smaller).&lt;br /&gt;
&lt;br /&gt;
B) Remove variable-length fields into&amp;nbsp;separate&amp;nbsp;tables.&lt;br /&gt;
&lt;br /&gt;
MySQL makes a distinction between &#39;static&#39; tables and &#39;variable-length&#39; tables. Basically, if the table contains any fields which are not fixed in size (such as VARCHAR or TEXT fields) it is treated as variable-length. MySQL treats these tables slightly differently, and can iterate static tables faster than variable-length tables. &amp;nbsp;If you had a table such as the following:&lt;br /&gt;
&lt;br /&gt;
Table Product (&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;id &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;INTEGER,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;cost &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; MEDIUMINT,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;weight &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;MEDIUMINT,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;description &amp;nbsp; &amp;nbsp;TEXT&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
You may find that access times will increase if you created a new table called Product_Descriptions, which only held the description field of Products. This example (and Vertical Partitioning in general) will not yield a performance benefit if the majority of your reads to this table also required reading the product description, as now you will also have to perform a join on nearly every query. If you only sometimes need the description, but find yourself reading the cost and weight often, then this type of partitioning may yield a nice performance boost in your application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;4) Horizontal Partitioning&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
Horizontal partitioning is a type of partitioning supported by MySQL. &amp;nbsp;It involves logically splitting a table into different physical locations, generally based on some sort of sorting value/function/hash. MySQL supports many different types of functions to use when partitioning a table. &amp;nbsp;The benefit of horizontal partitioning is that you keep the same logical table, and MySQL will take care of the details behind the scenes. &amp;nbsp;Each partition has its own index table, so performing queries become much more efficient. As an example, take a look at the following table definition:&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE Log_Entry (&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;id &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; INTEGER UNSIGNED NOT NULL PRIMARY KEY,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;type &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; TINYINT UNSIGNED NOT NULL&lt;br /&gt;
) PARTITION BY RANGE (type)&lt;br /&gt;
(&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;PARTITION p0 VALUES LESS THAN (10),&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;PARTITION p1 VALUES LESS THAN (100),&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;PARTITION p2 VALUES LESS THAN MAXVALUE&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
Data will now be placed into one of the three physical partitions based on the value of &#39;type&#39;. &amp;nbsp;The performance gain comes into play when performing queries on this table with &#39;type&#39; in the WHERE clause. The MySQL Optimizer is very good at pruning partitions, so in this scenario the &#39;type&#39; is in the where clause, MySQL will only search the partitions where the data could be placed in. &amp;nbsp;Naturally, this pruning prevents much of the data from being scanned, resulting in potentially large performance gains. Partitioning really shines when used on tables used primarily for storage, especially when that data may consist of hundreds of thousands to millions of records.&lt;br /&gt;
&lt;br /&gt;
This sounds like an easy way to get performance gains out of any database, but there IS a catch. &amp;nbsp;Horizontal partitioning cannot be used on tables which use Foreign Keys, nor can you use Foreign Keys to reference a partitioned table. &amp;nbsp;That being said, partitioning can still be used very effectively to get large performance boosts, and I would definitely suggest looking into using it as a performance optimization for large tables.&lt;br /&gt;
&lt;br /&gt;
While a quick google search will yield lots of information about horizontal partitioning in MySQL, here is a great&amp;nbsp;&lt;a href=&quot;http://chrismoos.com/2010/01/31/mysql-partitioning-tables-with-millions-of-rows/&quot;&gt;success story&lt;/a&gt;&amp;nbsp;where partitioning had a positive impact on a large database table.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;5) Triggers for data integrity&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
While not necessarily a performance optimization, using Triggers can be a good practice in regards to ensuring data integrity. &amp;nbsp;Triggers can be defined as &quot;Before Insert,&quot; &quot;After Insert,&quot; &quot;Before Delete,&quot; etc.. and thus can be used for all sort of great purposes. &amp;nbsp;Triggers can be used for logging, initializing or validating fields, performing certain operations or logic on other tables, the possibilities are quite endless. For a great in-depth tutorial on Triggers, check out this&amp;nbsp;&lt;a href=&quot;http://net.tutsplus.com/tutorials/databases/introduction-to-mysql-triggers/&quot;&gt;NetTut&#39;s tutorial&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are many more ways to optimize for better performance, and this post really just scratches the surface as far as what is possible in MySQL. &amp;nbsp;What do you think of these optimizations? &amp;nbsp;Do you have a great performance boost that others (like myself) may benefit from knowing? Do share!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brixican.blogspot.com/feeds/5649938615827568579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://brixican.blogspot.com/2011/04/mysql-database-performance.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/5649938615827568579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/5649938615827568579'/><link rel='alternate' type='text/html' href='http://brixican.blogspot.com/2011/04/mysql-database-performance.html' title='Common MySQL Database Performance Optimizations'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1870641221967095133.post-5145283631937626747</id><published>2011-03-27T20:56:00.001-04:00</published><updated>2011-03-29T00:45:48.203-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CakePHP"/><category scheme="http://www.blogger.com/atom/ns#" term="Yii"/><title type='text'>Initial thoughts on Yii..</title><content type='html'>My initial thoughts on the Yii PHP framework can be summed up in one word: &amp;nbsp;Hell yeah! &amp;nbsp;Okay, it was more like two words, but it doesn&#39;t change the fact that I am very impressed so far with Yii. &amp;nbsp;Admittedly I have not done any extensive work with the framework as of yet. &amp;nbsp;The majority of my experience with Yii to date has been reading the (very good) documentation, playing around with its code generation utilities, and looking at how the demo applications were built.&lt;br /&gt;
&lt;br /&gt;
So far the aspect of the framework I am most impressed with is how it is integrated with JQuery. &amp;nbsp;CakePHP injects javascript code throughout the page, a practice that most Jquery developers cringe at the thought of. &amp;nbsp;This is also why most Cake developers have&amp;nbsp;abandoned&amp;nbsp;the use of the JS helpers in favor of writing their own code. &amp;nbsp;This is why I like how Yii integrates JQuery so much: for the most part it separates the JQuery code into separate files and includes them at the top of the script. &amp;nbsp;This makes me happy. &amp;nbsp;This will also reduce the amount of time I spend creating my own custom JQuery scripts, since I will actually be using the helpful functions that are included with Yii.&lt;br /&gt;
&lt;br /&gt;
Another aspect of Yii that I am impressed with is its documentation. &amp;nbsp;Cake has some good documentation, but often key elements are outdated or missing. What is also frustrating is the lack of documented best practices to use with the framework. I often found my answers from blog posts or forums, and wondered why such simple answers weren&#39;t included in the documentation to begin with. &amp;nbsp;This is not the case with Yii. &amp;nbsp;The documentation itself is very thorough, updated constantly, and very clearly defines best practices. What&#39;s more is the generated code as well as the demos it ships with show the majority of the functionality shipped with Yii in use. &amp;nbsp;This is great because if I want to see how to create a form in Yii I can either consult the documentation or pull up any of the demos that came with the framework. Handy!&lt;br /&gt;
&lt;br /&gt;
Finally, the code generation utility shipped with yii is excellent. &amp;nbsp;In just a matter of minutes, Yii can generate a fully-functioning skeleton application complete with a login/logout system, contact form, CRUD, database access, etc.. all integrated with JQuery. &amp;nbsp;This has been a great skeleton to start with, and has managed to save me loads of setup time integrating basic components into the application. &amp;nbsp;(I can&#39;t say the same for Cake&#39;s skeleton application that is generated). &lt;br /&gt;
&lt;br /&gt;
When I began playing around with Yii, I fully expected to find parts of the framework where I would sit back and reminisce of my days in the Cake world. &amp;nbsp;To my surprise, the more I learn about Yii the happier I am to embrace it. &amp;nbsp;Nothing against Cake, but I would recommend Yii to any developer looking for a powerful MVC PHP framework.</content><link rel='replies' type='application/atom+xml' href='http://brixican.blogspot.com/feeds/5145283631937626747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://brixican.blogspot.com/2011/03/initial-thoughts-on-yii.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/5145283631937626747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/5145283631937626747'/><link rel='alternate' type='text/html' href='http://brixican.blogspot.com/2011/03/initial-thoughts-on-yii.html' title='Initial thoughts on Yii..'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1870641221967095133.post-321567537413317409</id><published>2011-03-20T21:44:00.001-04:00</published><updated>2011-03-21T18:23:53.763-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CakePHP"/><category scheme="http://www.blogger.com/atom/ns#" term="Yii"/><title type='text'>Switching PHP Framework from CakePHP to Yii</title><content type='html'>After about a year of developing with CakePHP, I have decided to make the switch to&amp;nbsp;&lt;a href=&quot;http://www.yiiframework.com/&quot;&gt;Yii&lt;/a&gt;. &amp;nbsp;There are several reasons I decided to make this switch, but the biggest one was performance related. &amp;nbsp;Don&#39;t get me wrong, I think CakePHP is a great development framework. &amp;nbsp;There were enough things that I personally did not like about Cakephp to justify my switch to learning a new MVC framework. &amp;nbsp;Here are a few of the reasons I decided to make the switch:&lt;br /&gt;
&lt;br /&gt;
1) Yii is PHP 5 only.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;I really like PHP 5. &amp;nbsp;While CakePHP supports PHP 5, it also has to support PHP 4, and thus does some things under the hood which hinders its performance a little in order to support legacy PHP code.&lt;br /&gt;
&lt;br /&gt;
2) Yii supports composite primary keys. &lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;One problem I had with CakePHP was how it did not support composite primary keys. &amp;nbsp;While this wasn&#39;t a huge deal breaker for me in Cake, it was definitely annoying. &amp;nbsp;Instead, every table had to have a unique ID as the sole primary key and your &quot;composite&quot; keys basically just had to be maintained through your own code. &amp;nbsp;Not terrible, but still rather annoying. &amp;nbsp;One thing I really did not like was how CakePHP thought that a &quot;Has One&quot; relationship should work in a database. &amp;nbsp;Take the example of Apple has one Banana. &amp;nbsp;Every textbook will tell you that to be in a proper normalized state, the Apple table will contain a field called &#39;banana_id&#39;, which will contain the ID of the corresponding Banana row. &amp;nbsp;This ensures that the Apple field can only contain one banana reference. &amp;nbsp;This is easily verified since Apple.banana_id holds one and only one value at a time. &amp;nbsp;Straight out of the&amp;nbsp;&lt;a href=&quot;http://book.cakephp.org/view/1041/hasOne&quot;&gt;CakePHP hasOne relationship documentation&lt;/a&gt;, it clearly states quite the opposite. &amp;nbsp;Does this produce a hasOne relationship? &amp;nbsp;Well, when you access models via Cake&#39;s API then sure it will hand you back one row, but your database is not in a normalized form. &amp;nbsp;There&#39;s technically nothing stopping you from firing up PhpMyAdmin and adding a few rows with the same Banana.apple_id. &amp;nbsp;This also means that if you are not careful with your queries or the way you access your data in Cake, you may end up with data redundancy. &amp;nbsp;This is why putting your databases in a normalized form is so important. There are ways around this in Cake but they require quite a bit of extra work, which of course defeats the purpose of its advertised &quot;magic&quot; in the first place.&lt;br /&gt;
&lt;br /&gt;
3) CakePHP is too slow for my needs.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;If you search google for &quot;CakePHP&quot; and &quot;Slow,&quot; you&#39;ll see many, many posts from developers wondering why they&#39;re application is responding so slowly. &amp;nbsp;You&#39;ll also notice that there are no real good answers as well. &amp;nbsp;Is CakePHP really that slow? &lt;br /&gt;
&lt;br /&gt;
The quick answer: &amp;nbsp;No actually, it isn&#39;t slow.&lt;br /&gt;
&lt;br /&gt;
Let me explain myself. &amp;nbsp;CakePHP can be fast. &amp;nbsp;By default however, it is very, very slow. &amp;nbsp;When you develop your application you will need to keep caching and performance in mind, something that most developers new to PHP frameworks don&#39;t do. &amp;nbsp;The problem is that in order to develop a fast CakePHP application, you cannot use the majority of the magic that Cake provides. &amp;nbsp;For example, Cake&#39;s documentation and tutorials will lead you to use mod_rewrite for pretty URLs (using .htaccess) and $this-&amp;gt;link() to create formatted html links quick and easily. &amp;nbsp;This creates a lot of easily maintainable functionality quickly, but your performance will suffer greatly down the road. &amp;nbsp;Even an application relying heavily on XCache and Memcached still needs lots of customized work tailored specifically to your application in order to speed it up. &amp;nbsp;While this will be true with an application developed in Yii as well, its default performance is significantly greater than Cake&#39;s. &amp;nbsp;So while people complaining that Cake is slow are not necessarily right, you will have to work hard to get it speedy.&lt;br /&gt;
&lt;br /&gt;
This post isn&#39;t meant to bash Cake. &amp;nbsp;I really do like the framework. &amp;nbsp;As I have gotten more used to developing in the MVC architecture I realize that Cake provided a great learning experience for me and worked as a great stepping stone in creating an MVC application. &amp;nbsp;I think that Yii will be the next step forward for my project, and future posts in this blog will hilight my experiences using Yii.&lt;br /&gt;
&lt;br /&gt;
Are you currently using CakePHP? &amp;nbsp;Did you end up switching to Yii, or another framework? &amp;nbsp;I&#39;d love to hear your thoughts!</content><link rel='replies' type='application/atom+xml' href='http://brixican.blogspot.com/feeds/321567537413317409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://brixican.blogspot.com/2011/03/switching-php-framework-from-cakephp-to.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/321567537413317409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/321567537413317409'/><link rel='alternate' type='text/html' href='http://brixican.blogspot.com/2011/03/switching-php-framework-from-cakephp-to.html' title='Switching PHP Framework from CakePHP to Yii'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1870641221967095133.post-6378041075441988025</id><published>2011-03-14T02:30:00.003-04:00</published><updated>2011-04-17T00:18:07.968-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Photoshop"/><category scheme="http://www.blogger.com/atom/ns#" term="Tutorials"/><title type='text'>Creating MARPAT digital camouflage textures with Photoshop</title><content type='html'>&lt;a href=&quot;http://www.fireteams.net/&quot;&gt;Fireteams.net&lt;/a&gt;&amp;nbsp;was in need of a camouflage texture. After a couple hours of scouring the web searching for a decent MARPAT (MARine PATtern) image, I gave up and decided to make my own. &amp;nbsp;I put together this little photoshop tutorial showing the techniques I used to create a Digital Desert Camouflage texture.&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Just a warning: I&#39;m a programmer, not an artist. &amp;nbsp;Also, my photoshop abilities are the result of following tutorials on the internet. If you know of better or easier ways to accomplish the same thing, I would love to hear about it in the comments!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Here is the final MARPAT camouflage image we&#39;ll be creating:&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwOHodzSN50d5ei2f7nulz645ZN_mfnAHjXCUamZaqcb2_HVPm7RJh16m4L9vicQl69U49Hc477oxKR2Ej4sTAszyxvUdXVbeQS2jiq9jHiIB9wQJk1iN8nqD-PFcB5XnPu61PvcVXaVBJ/s1600/marpat_fireteams.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwOHodzSN50d5ei2f7nulz645ZN_mfnAHjXCUamZaqcb2_HVPm7RJh16m4L9vicQl69U49Hc477oxKR2Ej4sTAszyxvUdXVbeQS2jiq9jHiIB9wQJk1iN8nqD-PFcB5XnPu61PvcVXaVBJ/s320/marpat_fireteams.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;MARPAT Digital Desert Camouflage&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
We&#39;ll start our tutorial by taking a quick look at real desert MARPAT camouflage. &amp;nbsp;This will give us a better idea of the look we want to achieve in our final image.&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidRmvpLQeQGS6SkqawGAakVnSWY29N8SQ0CMFAgLjVjPdqde6OT9wpKEOKbAbMLHeXVLNNoB5hnbnUXlefwb9drA27OMvvbwRpU6NIZCjCVbWtVom3v6D_KYSLI-z8nNExMAVyKZmjOgFv/s1600/real_marpat.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidRmvpLQeQGS6SkqawGAakVnSWY29N8SQ0CMFAgLjVjPdqde6OT9wpKEOKbAbMLHeXVLNNoB5hnbnUXlefwb9drA27OMvvbwRpU6NIZCjCVbWtVom3v6D_KYSLI-z8nNExMAVyKZmjOgFv/s320/real_marpat.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Sample of real desert MARPAT camouflage.&lt;br /&gt;
Courtesy of&amp;nbsp;http://www.helloelastic2.co.uk/justlooking/&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
It&#39;s easy to see that there are some unique characteristics that define MARPAT:&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Color&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;For Desert MARPAT, there are four colors which are used in the image.&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;Colors are layered with lighter colors underneath darker ones.&lt;/li&gt;
&lt;li&gt;Blobs become smaller and less connected as they get darker.&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;In digital desert camouflage, each color is a different shade of brown.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Shape&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Every blob-like shape in this image is composed of small square shapes.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Blobs tend to look stretched, flowing in more of a horizontal direction.&lt;/li&gt;
&lt;li&gt;Blobs are randomly shaped and have many holes in them.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div&gt;Now that we have some background on what we want to achieve, let&#39;s get started with our tutorial!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1)&lt;/b&gt; Begin by selecting four colors to use with your image. You can place each color into a swatch or paint them into a layer for easy access. &amp;nbsp;Here are the four colors I chose to use:&lt;br /&gt;
&lt;br /&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Base Color: &lt;/td&gt;&lt;td&gt;#d7cebd&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoKYttjJvKzyCJnV1Mi0zAkYi1XxFQFsMZqDP-aMXmkheIqCOwlFBCxUS5UtKwfaLhP6pnWIgFf5rX3cw9HR2jJ-uwN8RoCOiVhFiqXJgNUlTzi43XRKCwIy4nD4qkEv7m_I-2dxOSbgZH/s1600/base-color.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoKYttjJvKzyCJnV1Mi0zAkYi1XxFQFsMZqDP-aMXmkheIqCOwlFBCxUS5UtKwfaLhP6pnWIgFf5rX3cw9HR2jJ-uwN8RoCOiVhFiqXJgNUlTzi43XRKCwIy4nD4qkEv7m_I-2dxOSbgZH/s1600/base-color.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Light Color: &lt;/td&gt;&lt;td&gt;#c1b59c&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOzoCCPcD0RpEL4QJvv32z41B3l6o9ka6qIzLVI9QlgZVGM2fdidtz6IKZkzg3wRf2PW0-Dg6YR-EASLC9l3mScrkut-JqKq98jtvoPniip0rKPvkC1J1937K5AiWz_U1pKpNff_8lkmnj/s1600/light-color.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOzoCCPcD0RpEL4QJvv32z41B3l6o9ka6qIzLVI9QlgZVGM2fdidtz6IKZkzg3wRf2PW0-Dg6YR-EASLC9l3mScrkut-JqKq98jtvoPniip0rKPvkC1J1937K5AiWz_U1pKpNff_8lkmnj/s1600/light-color.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Medium Color:&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/td&gt;&lt;td&gt;#a99265&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOqwMe4ztzBXFtW4bLqE8X0LqKTdr-IZ6vo0oXbz6jdC2UBB3nJmUn9MP_DMeqIQ_1_BOq3O1_djT2b2JKk8hszZCQR41DZG6mdUFMlz2bhM0Zk-cW1vOx8naYc1FrkIHSCW6TU0drsXhh/s1600/medium-color.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOqwMe4ztzBXFtW4bLqE8X0LqKTdr-IZ6vo0oXbz6jdC2UBB3nJmUn9MP_DMeqIQ_1_BOq3O1_djT2b2JKk8hszZCQR41DZG6mdUFMlz2bhM0Zk-cW1vOx8naYc1FrkIHSCW6TU0drsXhh/s1600/medium-color.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Dark Color: &lt;/td&gt;&lt;td&gt;#88602b&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijQK3kXxZormL_ieSpUfRjlxlnYIB8dvbvK4H487FSglyv0YkyJ6iBPVI7A2kl-LXJk4hHuwMz0ghH0pem4lMGc_HqK0gGR56j9UMYiiec2uhiSvxA465xZTzj1LqFEGst2oOoPgjXXEO-/s1600/dark-color.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijQK3kXxZormL_ieSpUfRjlxlnYIB8dvbvK4H487FSglyv0YkyJ6iBPVI7A2kl-LXJk4hHuwMz0ghH0pem4lMGc_HqK0gGR56j9UMYiiec2uhiSvxA465xZTzj1LqFEGst2oOoPgjXXEO-/s1600/dark-color.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2)&lt;/b&gt; Make a new layer and paint it black. Apply a &quot;Difference Clouds&quot; filter on this layer:&lt;br /&gt;
&lt;br /&gt;
Filter &amp;gt; Render&amp;nbsp;&amp;gt;&amp;nbsp;Difference Clouds&lt;br /&gt;
&lt;br /&gt;
This will create a nice spread of light and dark shades which will help us to create our blob shapes later on.&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpOAu21qeDKpAv2t1WN2WWeJsLp96LM3y1p451GT8f3wjobtYqY0fcK0DeMPQVCC8jgb4HLgYC-Oj31JVgZqqP3VqnERUvWPZzEcYOTR_WTBXGCOnFDc1by5KVLFdeBrpcwHaZGnH2WRVH/s1600/difference_clouds.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpOAu21qeDKpAv2t1WN2WWeJsLp96LM3y1p451GT8f3wjobtYqY0fcK0DeMPQVCC8jgb4HLgYC-Oj31JVgZqqP3VqnERUvWPZzEcYOTR_WTBXGCOnFDc1by5KVLFdeBrpcwHaZGnH2WRVH/s320/difference_clouds.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Difference Clouds!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3)&lt;/b&gt; Increase the contrast of the clouds. &amp;nbsp;This can be done through the following menu option:&lt;br /&gt;
&lt;br /&gt;
Image&amp;nbsp;&amp;gt; Adjustments&amp;nbsp;&amp;gt; Brightness / Contrast&lt;br /&gt;
&lt;br /&gt;
Increase the contrast to a value between 75 and 100. &amp;nbsp;I used a value of 90 for each of my cloud layers.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAYgREm-4IlLDZpV56SMc6hN-Zlalya5uvgOgJQbM0KyYK4QFM4zpxgrj0gT7mISykYHeA37p3ky9NHRYdEdbyX3Dzz3u1Tfaj10uBl3Rf4F3bV6wgdSKXs0S9v_P3z5SwmkDmIJnMRAIB/s1600/difference_clouds_contrast.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAYgREm-4IlLDZpV56SMc6hN-Zlalya5uvgOgJQbM0KyYK4QFM4zpxgrj0gT7mISykYHeA37p3ky9NHRYdEdbyX3Dzz3u1Tfaj10uBl3Rf4F3bV6wgdSKXs0S9v_P3z5SwmkDmIJnMRAIB/s320/difference_clouds_contrast.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;4)&lt;/b&gt; Apply a mosaic filter to the clouds:&lt;br /&gt;
&lt;br /&gt;
Filter &amp;gt; Pixelate &amp;gt; Mosaic&lt;br /&gt;
&lt;br /&gt;
Select a small cell size, I chose a size of 5. &amp;nbsp;Sizes of 7-8 will produce images that look more zoomed in. &amp;nbsp;The cell size will represent the smallest &quot;square&quot; that will be in the image. &amp;nbsp;I encourage playing around with this value until you find the size you desire.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioe3np8rBwaTfqbGn5OMDlYOTrB1Z-mqbTQW0eCneaBFu2RZ7gILPkz5kT9xCf5w4RSABcoS2PFk91BSG_xgTTI-Iqwt2XItSA-S7zfVNynNp5wtyPonCUTLuBNoR6CgYlni9U7gqEM879/s1600/difference_clouds_mosaic.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioe3np8rBwaTfqbGn5OMDlYOTrB1Z-mqbTQW0eCneaBFu2RZ7gILPkz5kT9xCf5w4RSABcoS2PFk91BSG_xgTTI-Iqwt2XItSA-S7zfVNynNp5wtyPonCUTLuBNoR6CgYlni9U7gqEM879/s320/difference_clouds_mosaic.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;5)&lt;/b&gt; Repeat steps 2 through 4 two more times. This will give us a total of three layers of pixelated difference clouds. &amp;nbsp;The variability found in each cloud layer will help prevent our blobs from having too similar of patterns.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;6)&lt;/b&gt; Now that we have our clouds, it is time to start creating our camouflage! &amp;nbsp;We&#39;ll start with the lightest color first: the Base color. &amp;nbsp;Make a new layer and use the paint bucket tool to color the layer with our Base color. That&#39;s it! (at least for this layer). &amp;nbsp;I wish the other layers were this easy though...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;b&gt;7)&lt;/b&gt; Before we continue, I would like to quickly explain what we are going to try and accomplish here. &amp;nbsp;Using the Magic Wand Tool, we&#39;re going to select multiple areas of a cloud layer (by holding the Shift key while selecting with the wand), then fill-in our selection with one of our three remaining colors.&amp;nbsp;If while clicking around you accidently let go of shift (and lose all of your selections), just hit ctrl-z to get all your work back. We will use a different cloud image for each of our colors.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Select the Magic Wand Tool (W is the keyboard shortcut) and choose a very small Tolerance. I chose a value of 2. You can play around with larger values, but I recommend no larger than 4. For this layer we&#39;re going to create the Light color portion of the camo. This color should cover about 75% of the base color, and should contain large, connected blobs. &amp;nbsp;Here are a couple images of my selections in progress. This will give you a good idea on how to progress.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ-75km45la6r6kcKPzmwJocGdpbDD9YmzyZTIALzIyX9WULPNh_LYojeTt4oXBx9PwK5RgKUIKEqA-J-HXghY3rZTgchCClPq4xrJBvAqBuXfEiUuMIQwvzJi08jdgucTZvyq3hC0XWtN/s1600/Picture+1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ-75km45la6r6kcKPzmwJocGdpbDD9YmzyZTIALzIyX9WULPNh_LYojeTt4oXBx9PwK5RgKUIKEqA-J-HXghY3rZTgchCClPq4xrJBvAqBuXfEiUuMIQwvzJi08jdgucTZvyq3hC0XWtN/s320/Picture+1.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Result after a few shift-clicks&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7ZtLaxDpcpDGfS2LMDVS2UC7ccXRnRpFh4OT1-E1NGtvlKROh6Aws0xCJ-QKt3fvezbr3pqszh2iQCPphW4pdaVQdQegygN7-dfxA3qkc3ex0fIjIO50BkoQpW051eOdpo8WNzjRPa9Ii/s1600/light_selection.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7ZtLaxDpcpDGfS2LMDVS2UC7ccXRnRpFh4OT1-E1NGtvlKROh6Aws0xCJ-QKt3fvezbr3pqszh2iQCPphW4pdaVQdQegygN7-dfxA3qkc3ex0fIjIO50BkoQpW051eOdpo8WNzjRPa9Ii/s320/light_selection.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Final selection. Takes a while, but I swear it is worth it!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;b&gt;8) &lt;/b&gt;Now that we have our selection, copy (Ctrl-C) and paste (Ctrl-V) your selection into a new layer. &amp;nbsp;Set a color overlay on this layer to the color you chose for your Light color. &amp;nbsp;This can be done through:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Layer &amp;gt; Layer Style &amp;gt; Color Overlay&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Make sure that Blend Mode is set to Normal, and Opacity to 100%. &amp;nbsp;Click on the colored icon, and set it to your color. &amp;nbsp;This is only one of many ways to set the color for our selection. I like this method as it makes it very easy to change the color of the entire layer at once (especially handy if you want to change the color later).&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtBcLaXfEke5nySunkaOX6vhC4lD8ylL_zMV1h-rwlcZcGkdb4uZvJGNXU2Fl6nmLKXt8ovT5Furd0PzFydbHpE6OdHsjcUMkbEFv0UypeD79wj7XDYZcCv1UBPuSbMTAYBIkvZTXx4wN2/s1600/Picture+3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtBcLaXfEke5nySunkaOX6vhC4lD8ylL_zMV1h-rwlcZcGkdb4uZvJGNXU2Fl6nmLKXt8ovT5Furd0PzFydbHpE6OdHsjcUMkbEFv0UypeD79wj7XDYZcCv1UBPuSbMTAYBIkvZTXx4wN2/s320/Picture+3.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Result after a copy and paste. &amp;nbsp;I moved the Base layer&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;above the&amp;nbsp;clouds so that we can actually see the selection.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXSUmgq0dLiepnHbVLqOeZxD4VMD5TOGZlzZfa-GQjfGUE_o6pESsoYQLUxBaJf_X11i-CpFizVRWxiP3BnZVPiTH6zHZg9CV8zBU5aC7S-8h1h9Gz1ZKaDQUyimY-JeMTU5svJNbRu5aD/s1600/light_final.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXSUmgq0dLiepnHbVLqOeZxD4VMD5TOGZlzZfa-GQjfGUE_o6pESsoYQLUxBaJf_X11i-CpFizVRWxiP3BnZVPiTH6zHZg9CV8zBU5aC7S-8h1h9Gz1ZKaDQUyimY-JeMTU5svJNbRu5aD/s320/light_final.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Result after setting the blending options. Finally starting&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;to look like camouflage.&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;9) &lt;/b&gt;Repeat steps 7-9 for our next two colors, using a different cloud layer for each color. Remember that these blobs get smaller and less connected as they get darker. Below are the results for my next two colors:&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWT0ik8iC7Qt_SspjF2DECy5udFBuhxpemY1JyZ_Wy5gbdHpcN7lcgKuFBtzy_ITzhDuo_ulRTt9TzX1UKYJFc6BDjhsr9ukn8_DY4c3FT3PyXz5DFsHevgYnCh7WCD5im4LT48q1e1DNK/s1600/medium_selection.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWT0ik8iC7Qt_SspjF2DECy5udFBuhxpemY1JyZ_Wy5gbdHpcN7lcgKuFBtzy_ITzhDuo_ulRTt9TzX1UKYJFc6BDjhsr9ukn8_DY4c3FT3PyXz5DFsHevgYnCh7WCD5im4LT48q1e1DNK/s320/medium_selection.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Selection mask for Medium color.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL7DwPPrQ509Z9C8MRkvECg2uAd1OzfFVz60pPinxGyJ6vsCqa9094mT_4Yf74mHYTrg8v0RpggBn2Kf_ttIHQoahEhksRMNy-K-aaQyVhTuJ3ErOu645urJxL024B6QzwYx5hcIepNJtq/s1600/medium_final.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL7DwPPrQ509Z9C8MRkvECg2uAd1OzfFVz60pPinxGyJ6vsCqa9094mT_4Yf74mHYTrg8v0RpggBn2Kf_ttIHQoahEhksRMNy-K-aaQyVhTuJ3ErOu645urJxL024B6QzwYx5hcIepNJtq/s320/medium_final.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Result after applying medium color layer.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;span id=&quot;goog_1331312196&quot;&gt;&lt;/span&gt;&lt;span id=&quot;goog_1331312197&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd4Okie3kygj5LNZFlvfoxSkm1ckkncLHeyHLLhevIfoiPcGLZHhpKQY9wagcPrXOWJiXPH6dzy1CxAvyiq6ho9LZYqYrnDnbvc0adZv9Ug4kaKSTPPFg_dxBkDdYO57OOCidPgzbtTjqT/s1600/dark_selection.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd4Okie3kygj5LNZFlvfoxSkm1ckkncLHeyHLLhevIfoiPcGLZHhpKQY9wagcPrXOWJiXPH6dzy1CxAvyiq6ho9LZYqYrnDnbvc0adZv9Ug4kaKSTPPFg_dxBkDdYO57OOCidPgzbtTjqT/s320/dark_selection.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Dark color selection mask.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpyOiG6Qao64k__0vzJCc_tKvpm4ZVGtInCvOIVKR2mQNiL9_btd3Orkd-9x8kOcc_MGOhhy0oczhH27KZcsEkDj-7cdDSsqOsSuXLXTeeplpRG_FFwneNXojgxOMz6l9Bqra0q05qvsRw/s1600/dark_final.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpyOiG6Qao64k__0vzJCc_tKvpm4ZVGtInCvOIVKR2mQNiL9_btd3Orkd-9x8kOcc_MGOhhy0oczhH27KZcsEkDj-7cdDSsqOsSuXLXTeeplpRG_FFwneNXojgxOMz6l9Bqra0q05qvsRw/s320/dark_final.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Final camouflage image&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
That is all there is to it! This technique can be done on a larger scale to produce nice backgrounds or textures in games. If this tutorial was useful to you, or you found better techniques or easier ways to accomplish things, please let me know in the comments!&lt;br /&gt;
&lt;br /&gt;
Hope you found this useful!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brixican.blogspot.com/feeds/6378041075441988025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://brixican.blogspot.com/2011/03/creating-marpat-digital-camouflage.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/6378041075441988025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/6378041075441988025'/><link rel='alternate' type='text/html' href='http://brixican.blogspot.com/2011/03/creating-marpat-digital-camouflage.html' title='Creating MARPAT digital camouflage textures with Photoshop'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwOHodzSN50d5ei2f7nulz645ZN_mfnAHjXCUamZaqcb2_HVPm7RJh16m4L9vicQl69U49Hc477oxKR2Ej4sTAszyxvUdXVbeQS2jiq9jHiIB9wQJk1iN8nqD-PFcB5XnPu61PvcVXaVBJ/s72-c/marpat_fireteams.png" height="72" width="72"/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1870641221967095133.post-6933829591821051650</id><published>2010-02-05T17:30:00.002-05:00</published><updated>2011-03-10T10:03:14.003-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JQuery"/><title type='text'>Jquery Map Hilight Plugin</title><content type='html'>For anyone out there using HTML Image Maps who wish to have areas of the map light up, hilight, or a few other effects, I highly recommend checking out the Map Hilight plugin for JQuery. What the plugin does is apply an effect to every area in the image map, so when that area is clicked, hovered over, etc.. the area will become &quot;hi-lighted.&quot; &amp;nbsp;MapHilight is really easy to setup, once you have an image map created, you simply apply the effects using the following call:&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;$(&quot;#ImageID&quot;).maphilight();&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
and that&#39;s it! &amp;nbsp;There are quite a few effects that you can customize. &amp;nbsp;There are multiple ways to change the defaults, but the easiest is to include this snippet in your JS code and change the values as needed:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;$.fn.maphilight.defaults = {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; &gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;fill: true,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; &gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;fillColor: &#39;000000&#39;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;fillOpacity: 0.2,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; &gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;stroke: true,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; &gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;strokeColor: &#39;ff0000&#39;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; &gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;strokeOpacity: 1,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; &gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;strokeWidth: 1,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; &gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;fade: true,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; &gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;alwaysOn: false&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; &gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
There is much more you can do with this plugin, but this is an easy way to apply basic effects to any image map. &amp;nbsp;This library becomes even more powerful / easy to use if you combine it with the JQuery Metadata plugin. &amp;nbsp;Both plugins can be found here:&lt;br /&gt;
&lt;a href=&quot;http://plugins.jquery.com/project/maphilight&quot;&gt;http://plugins.jquery.com/project/maphilight&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://plugins.jquery.com/project/metadata&quot;&gt;http://plugins.jquery.com/project/metadata&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Documentation for Map Hilight can also be found here:&lt;br /&gt;
&lt;a href=&quot;http://davidlynch.org/js/maphilight/docs/&quot;&gt;http://davidlynch.org/js/maphilight/docs/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://brixican.blogspot.com/feeds/6933829591821051650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://brixican.blogspot.com/2010/02/jquery-map-hilight-plugin.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/6933829591821051650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/6933829591821051650'/><link rel='alternate' type='text/html' href='http://brixican.blogspot.com/2010/02/jquery-map-hilight-plugin.html' title='Jquery Map Hilight Plugin'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1870641221967095133.post-8559046700662981058</id><published>2009-12-24T20:13:00.002-05:00</published><updated>2011-11-09T18:59:24.642-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Game Theory"/><title type='text'>Cell to Cell Distance in a 2D Hexagonal Tile Map</title><content type='html'>I needed to grab the distance between any two cells in a hex grid, and I found it was more difficult than I originally thought it would be..  There were lots of blogs and theory sites which had distance formulas, but none of them worked for every cell in the grid, and most of them didn&#39;t work at all! Wtf! Most of them didn&#39;t even work on the grids they claimed they worked on.. I ended up creating my own distance function, feel free to use it if you find it handy!&lt;br /&gt;
&lt;br /&gt;
FireTeams uses an isometric hex-tile grid for its game.  Once your tiles have been made, these grids are fairly simple to create and implement.  The only real trouble I had with this style of grid was grabbing the distance (measured by the number of tiles a unit would have to traverse) between any two tiles on the grid.  Here&#39;s the function as a whole, I&#39;ll proceed to explain each part throughout the rest of the post: &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Update:&lt;/b&gt; An anonymous poster found a bug in my implementation below, and graciously posted a fixed-up version! See the comments for his working algorithm. Thanks, Anonymous!!&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;var dx = Math.abs(start.x - end.x);&lt;br /&gt;
var dy = Math.abs(start.y - end.y);&lt;br /&gt;
var distance = 0;&lt;br /&gt;
&lt;br /&gt;
if (dx &amp;lt; dy/2 )&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;distance = dy;&lt;br /&gt;
else&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;distance = dy + dx - Math.floor(dy/2.0);&lt;br /&gt;
&lt;br /&gt;
if (start.y % 2 == 0)&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (dy % 2 == 1 &amp;amp;&amp;amp; start.x &amp;gt; end.x)&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;distance--;&lt;br /&gt;
else&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (dy % 2 == 1 &amp;amp;&amp;amp; start.x &amp;lt; end.x)&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;distance--;&lt;br /&gt;
&lt;br /&gt;
return distance;&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
The distance formula wasn&#39;t as simple as it is in a standard square-tile grid.  For one, the hex-tile grid allows units to move in exactly 6 directions instead of the 4 or 8 (if diagonal movement is allowed) directions of movement.  Two, because of the nature of hex tiles, every other row or column (I guess this depends on how your tiles are oriented), is offset.  The grid implementation I used is as follows: &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://i33.photobucket.com/albums/d97/brixican/Hex_grid_coordinates.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;282&quot; src=&quot;http://i33.photobucket.com/albums/d97/brixican/Hex_grid_coordinates.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
When the tiles are layed out in this format, it&#39;s easy to see that the Y coordinates increase at approximately twice the rate as the X coordinates when traversing the tiles south.  This gives us a really easy special case for the distance:&lt;br /&gt;
&lt;br /&gt;
if (dx &amp;lt; dy / 2)       distance = dy;&lt;br /&gt;
&lt;br /&gt;
In other words, any time the horizontal distance is less than half the vertical distance, the shortest path between the two cells will always be the vertical distance.  For example, starting at cell &amp;lt;0,0&amp;gt; on the grid above, the cells &amp;lt;0,7&amp;gt; through &amp;lt;3,7&amp;gt; can all be reached in exactly 7 steps.&lt;br /&gt;
&lt;br /&gt;
In fact, the minimum distance between any two cells can be visualized pretty simply:  travel diagonally towards the cell until your y-coordinates are the same, then travel horizontally until you&#39;ve reached the cell.  This leads us to the more general case for the distance between our hex tiles:&lt;br /&gt;
&lt;br /&gt;
distance = dy + dx - Math.floor(dy / 2.0);&lt;br /&gt;
&lt;br /&gt;
This term requires a slight bit of explaining.  Since the shortest path between two cells require traveling vertically and horizontally, it makes sense to add the dy and dx terms together.  This over-estimates the actual distance.  This can be seen easily by looking at the distance to go from cell &amp;lt;0,0&amp;gt; to cell &amp;lt;4,7&amp;gt;.  Adding the dx and dy terms (which are 4 and 7 respectively) give us a distance of 11, while the actual distance is only 8.  The distance of 11 would be true if our unit were to travel directly south, then directly east.  Since we are trying to get to cell &amp;lt;4,7&amp;gt; in the shortest distance, we would actually travel along the diagonal all the way down to cell &amp;lt;3,7&amp;gt;, and then move one more east to cell &amp;lt;4,7&amp;gt;.  To compensate for this shorter distance, we can use our observation from above:  when traveling south in a diagonal, the x-coordinate increases at half the rate the y-coordinate does.  You can see on the grid, when traveling in the diagonal from &amp;lt;0,0&amp;gt; to &amp;lt;3,7&amp;gt;, the distance dx increases by 1 tile everytime dy increases by 2.  The further we travel along a diagonal, the bigger this dx term gets.  This increase in dx is not wanted in our calculation, since these extra tiles do not need to be traversed in order to get to our destination, so we want to subtract them.  The term:&lt;br /&gt;
&lt;br /&gt;
Math.floor(dy / 2.0)&lt;br /&gt;
&lt;br /&gt;
gives us that extra distance generated for dx as dy increases, so we can simply subtract this from the addition of dy and dx to get our distance! Yay!&lt;br /&gt;
&lt;br /&gt;
...Almost done!  Most tiles will now give correct distances, but not all of them.  There is still one more special case we have to tackle, and this is a direct cause of the offsetting done on a row x row basis.  Because the X-coordinate is offset every other row, about 1/4 of our calculated tiles get calculated by 1 too many tiles. Cells sitting on the offset rows are overestimated by 1.  In particular, depending on which row our start tile is in, either the tiles in the odd rows on the east of the start tile are overestimated, or the tiles on the west side of the tile are overestimated.  This is an easy special case:&lt;br /&gt;
&lt;br /&gt;
if (start.y % 2 == 0)&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (dy % 2 == 1 &amp;amp;&amp;amp; start.x &amp;gt; end.x)&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;distance--;&lt;br /&gt;
else&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (dy % 2 == 1 &amp;amp;&amp;amp; start.x &amp;lt; end.x)&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;distance--;&lt;br /&gt;
&lt;br /&gt;
In other words, for the first half of the statement, if our start tile is in a non-offset row, and our dy term is even, and the destination tile is west of the start tile, then our distance will be over-estimated, and we should decrease by a value of 1.  If our start tile is on an offset row, then the over-estimated tiles are to the east of the start tile.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So there you have it!  A simple function for calculating the distance between any two cells in a hex-tile grid.  I hope others find this useful as well!  Cheers, and I hope everyone has a good Christmas Eve!</content><link rel='replies' type='application/atom+xml' href='http://brixican.blogspot.com/feeds/8559046700662981058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://brixican.blogspot.com/2009/12/cell-to-cell-distance-in-2d-hexagonal.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/8559046700662981058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/8559046700662981058'/><link rel='alternate' type='text/html' href='http://brixican.blogspot.com/2009/12/cell-to-cell-distance-in-2d-hexagonal.html' title='Cell to Cell Distance in a 2D Hexagonal Tile Map'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1870641221967095133.post-6414254121157970999</id><published>2009-12-24T17:50:00.000-05:00</published><updated>2009-12-24T17:50:38.875-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Miscellaneous"/><title type='text'>First Blog</title><content type='html'>This is the first of many blogs to come. &amp;nbsp;These blogs will focus on algorithms, solutions to problems I ran into, and interesting snippets of code which I come across on my path to developing &lt;a href=&quot;fire-teams.com&quot;&gt;fire-teams.com&lt;/a&gt;. &amp;nbsp;The game is being built with JQuery for the interface and AJAX, and CakePHP for the back-end. &amp;nbsp;In future posts I&#39;ll describe fire-teams itself in more detail!</content><link rel='replies' type='application/atom+xml' href='http://brixican.blogspot.com/feeds/6414254121157970999/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://brixican.blogspot.com/2009/12/first-blog.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/6414254121157970999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1870641221967095133/posts/default/6414254121157970999'/><link rel='alternate' type='text/html' href='http://brixican.blogspot.com/2009/12/first-blog.html' title='First Blog'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>