Archive for May, 2009

Problem 1 - Add all the natural numbers below one thousand that are multiples of 3 or 5

// May 26th, 2009 // 2 Comments » // Project Euler

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.

About Project Euler

// May 22nd, 2009 // No Comments » // Project Euler

I found these challenges very useful to the development and assessment of my programming abilities. From now I I will post a question from the Project Euler website as a challenge to all readers who have an interest in programming. Ideally the solutions will be submitted in PHP, but other languages will be accepted. I will post a challenge every Monday to give you the week to work on it and from the order of the submitted solutions we will know who came up with the answer first.

What is Project Euler?

Project Euler is a series of challenging mathematical/computer programming problems that will require more than just mathematical insights to solve. Although mathematics will help you arrive at elegant and efficient methods, the use of a computer and programming skills will be required to solve most problems.

The motivation for starting Project Euler, and its continuation, is to provide a platform for the inquiring mind to delve into unfamiliar areas and learn new concepts in a fun and recreational context.

Funny ways to document code

// May 22nd, 2009 // No Comments » // Programming

While I do try to document my code as best and efficiently as I can, I will admit that sometimes I like to get creative. As I was updating a particular file, I came accorss an old block of code that read as follows:

/********************
* Product lists holder
* Contains 1 table with 3 columns
* I can’t figure out a way to automate this.
* Logic: List is alphabetical, BUT we HAVE to plop in some products from a different letter group
* Problem: The out-of-place products need to be placed in a specific place (where they told me to place it in the list, in case you’re wondering)
*            This means I can’t find a way to have a product find it’s own place in the list. This causes me to hard code each product link,
*            thus, I can’t automate looping all 3 columns in one smooth loop.
* To my replacement: If you can come up with a way to fix this mess email me at xxxx@gmail.com and let me know how you did it
*/

You are all free to flame me for this if you wish, but hey, I was younger and less experienced. The problem I faced that prompted to write that comment is having to display the company products in alphabetical order in 3 columns. That was easy enough, but the problem came when customers started complaining that they couldn’t find certain products. Lets say one product is called Super Product, and another product or very similar features and quality is called A-Super Product, that “A” made it fall into the -A- section of the alphabetic list. Now I am tasked with puting A-Super Product next to Super Product in the list. And the rest is explained in the comment code above.

Now I wonder who else has done similar things, leave your “creative documentation in comments below.

War on drugs

// May 22nd, 2009 // No Comments » // Funny

NOTE: I don’t condone the use of illegal substances…now that I can’t be sued, or yelled at by angry parents, I bring you the following:

1242269707223_f

SEO Friendly URLs with Zend Framework

// May 21st, 2009 // 9 Comments » // Zend Framework

Friendly URLs with ZendToday I will talk about defining custom friendly URLS with Zend Framework. If you’re thinking that the Zend Framework already provides SEO friendly URLs, well, you’re absolutely right. Zend’s MVC set up provides a very clean URL format in which a controller combined with an action gives you a specific page. Then variables that need to be passed to a particular page are passed in the URL.

For example, you may have

www.mywebsite.com/products/detail/id/15 where products is the controller, detail is your view and id is a parameter with the value of 15

or

www.mywebsite.com/article/view/slug/seo_urls where article is the controller, view is the view and slug is a parameter with the value of seo_urls

You can already see the string getting longer, and it’s not really how you want to see your URLs being displayed. Thankfully Zend has an easy fix for this, and you don’t even need an .htaccess file to do it.

Enter the rewrite router operation to the rescue!!

There are 6 types of routes, where #6 is special in that it is the one that is used by default by Zend to router controllers, actions and modules:

  1. Zend_Controller_Router_Route
  2. Zend_Controller_Router_Route_Static
  3. Zend_Controller_Router_Route_Regex
  4. Zend_Controller_Router_Route_Hostname
  5. Zend_Controller_Router_Route_Chain
  6. Default Routes

To use any of the 6 router types, you must first instantiate them with getRouter() which returns a rewrite router by default.

$router = $front->getRouter(); // returns a rewrite router by default

Zend_Controller_Router_Route

The Zend_Controller_Router_Route is the router type I use most often…so far.  It is easy to use and can be used to define dynamic and static routes. More on static routes later.

Lets look at an example where we want to have a URL that routes to a product’s detail page based on the product’s unique slug

www.mywebsite.com/product/product_slug

//Router: Product detail

$router = $front->getRouter(); // returns a rewrite router by default
$route = new Zend_Controller_Router_Route(
‘product/:slug’,
array(
‘controller’    => ‘product’,
‘action’        => ‘detail’,
),
array(’year’ => ’^[a-zA-Z0-9_]*$’)
);

$router->addRoute(’product’, $route);

Ok, lets go over the code above.

$router = $front->getRouter();

Next you need to create your custom route, you do that by using the Zend_Controller_Router_Route() function which takes 2 parameters and 1 optional parameter:

  1. A string with the route definition that will be matched to a URL
  2. An ass0siative array with a controller and an action that the pattern will map to.
  3. An optional variable requirement

Notice that in the route definition ‘product/:slug’ the ‘:slug’ part of the definition is a parameter which is passed to the target script. There you will be able to access all variables by means of the Zend_Controller_Action::_getParam() or Zend_Controller_Request::getParam() methods:

$slug= $request->getParam(’slug’);
$slug= $this->_getParam(’slug’);

You can additionally give the parameter a default value by adding them to the array where you specify the controller and action to use with the route:

array(
’slug’            =>    ‘product_slug’,
‘controller’    => ‘product’,
‘action’        => ‘detail’,
)

The 3rd parameter which is an optional regular expression that is used to define what kind of values are acceptable for each variable. In our case we want to match only letters, numbers and underscores. So any other characters would fail the test and the variable will be given whatever we set as default.

array(’year’ => ’^[a-zA-Z0-9_]*$’)

Zend_Controller_Router_Route_Static

The static router is a simpler version of Zend_Controller_Router_Route, meaning that if you have a route that will never change, then there is no need to fire up the regular expression engine. So if you have www.mywebsite.com/login, which will never have a parameter passed to it, you would use:

$route = new Zend_Controller_Router_Route_Static(
‘login’,
array(’controller’ => ’user’, ’action’ => ’login’)
);
$router->addRoute(’login’, $route);

Zend_Controller_Router_Route_Regex

This route type uses regular expressions instead of parameters when defining the route. It is a little more complex than the other route types, but it is more flexible and faster. Lets start with another example, lets say we want to go to an article archive page based on year and month:

$route = new Zend_Controller_Router_Route_Regex(
‘archives/(\d+)/(\d+)‘,
array(
‘controller’ => ’archive’,
‘action’ => ’show’
)
);
$router->addRoute(’archive’, $route);

Notice we have 2 regular expressions, both are(\d+) which match numbers. Our controller and actions are set. The router works just like the 2 previous routers exept that we don’t have variable names for the parameters. Instead they are assigned integest, NOT STRINGS, starting from 1. So to retrieve the values for www.mywebsite.com/archives/2009/01

$request = $this->getRequest();

$year    = $request->getParam(1); // $year = ’2009′;
$month   = $request->getParam(2); // $month = ’1′;

These are integers, NOT strings, so don’t use

$year    = $request->getParam(’1′);

Zend_Controller_Router_Route_Hostname

Zend_Controller_Router_Route_Hostname is the hostname route of the framework. It works similar to the standard route, but it works on the with the hostname of the called URL instead with the path.

Let’s use the example from the standard route and see how it would look like in a hostname based way. Instead of calling the user via a path, we’d want to have a user to be able to call http://martel.users.example.com to see the information about the user “martel”:

$hostnameRoute = new Zend_Controller_Router_Route_Hostname(
‘:username.users.example.com’,
array(
‘controller’ => ’profile’,
‘action’ => ’userinfo’
)
);

$plainPathRoute = new Zend_Controller_Router_Route_Static(”);

$router->addRoute(’user’, $hostnameRoute->chain($plainPathRoute);

The first parameter in the Zend_Controller_Router_Route_Hostname constructor is a route definition that will be matched to a hostname. Route definitions consist of static and dynamic parts separated by the dot (’.') character. Dynamic parts, called variables, are marked by prepending a colon to the variable name: :username. Static parts are just simple text: user.

Hostname routes can, but never should be used as is. The reason behind that is, that a hostname route alone would match any path. So what you have to do is to chain a path route to the hostname route. This is done like in the example by calling $hostnameRoute->chain($pathRoute);. By doing this, $hostnameRoute isn’t modified, but a new route (Zend_Controller_Router_Route_Chain) is returned, which can then be given to the router.

Zend_Controller_Router_Route_Chain

Sorry but I don’t fully grasp this concept yet so I am unable to talk about it here. I will refer you to the Zend documentation page for Zend_Controller_Router_Route_Chain instead

Zend Framework DB Access

// May 20th, 2009 // 1 Comment » // Zend Framework

logo-zend-frameworkBack when I first started using the Zend Framework one of the first questions that I wanted answered was “how do I extract data from my database, and how do I write back?”. Of course the first place I went to was the documentation. Along the way I found some tutorials and some videos, including the video below. While it all works,  in all honesty, I was not able to get a lot of the samples provided by Zend to work for me, but for the most part the video was a great tool.

The video is at the bottom of the post. So I will recap the video first and tell you how I went about using each of the components and provide some of my own source code as examples.

First, setting up a connection to the database

From the 2 methods provided by the video, I used a configuration file to store my database information.  I did this because, well, I was able to get it to work the first time I tried it, but it’s also very easy to maintain since it removed those lines of code from and places them neatly in a separate file.

Here is the way my config.ini file looks like, notice that I can declare a parameters for multiple connection strings. In my case I have 2 databases that  need to talk to each other. Also note that the config.ini file is located in the applications folder if you follow the directory structure recomended by Zend.

[firstDbConnect]
db.adapter = PDO_MYSQL
db.params.host = localhost
db.params.username = mydbname
db.params.password = mypassword
db.params.dbname = mydbname
[secondDbConnect]
db.adapter = PDO_MYSQL
db.params.host = localhost
db.params.username = anotherusername
db.params.password = anotherpassword
db.params.dbname = seconddb

Once I had my .ini file in place, I needed to read the file, and for that, we use Zend_Config()
$config = new Zend_Config_Ini(’../application/config.ini’, ‘firstDbConnect’);

Now, this is were I stray. The video says to pass the values of $config->db to Zend_Db::factory(), but instead I read them into the global registry so that I could later call them from any class or other part of the project.

I did that like this:

$registry = Zend_Registry::getInstance();
$registry->set(’config’, $config);

Then, inside a class I can connect to the database like so:

$db = Zend_Db::factory(Zend_Registry::get(’config’)->db);

Next is how to run a SQL Query & Fetching results

This one is straight forward, all you have to do is use the method fetchAll() and supply it with your query. The fetchAll method returns an array of rows as your record set. Each row is an associative array which you can loop through with a foreach() loop.

Puting a database connection from above with a query looks like this:

$db = Zend_Db::factory(Zend_Registry::get(’config’)->db);
$sql = “SELECT * FROM users”;
$results = $db->fetchAll($sql);

Looping through the returned rows stored in $results looks like this:

foreach($result as $row){

echo $row["username"];

}

It’s as simple as that. Just remember that you’re looping through an array, not an object, so you need to access the array elements  as an array and not as an object.

Preparing a SQL Query

This section of the video talks about ‘preparing’ queries. By using the prepare() method you can create a query and assign a parameter place holder which is where you parameter values will be inserted before the query is executed. The thing to notice here is that the value you give the query is not simple appended to the query, instead, the value gets passed to the RDBMS server where it is combined with a machine usable compiled version of the query, this is good to know since it means that this is a good line of defense against SQL injections.

$stmt = $db->prepare(’SELECT * FROM users WHERE user_status= ?’)

Then you execute the query, giving it your parameter value, in this case ‘active’ and store returned rows

$stm->execute(array['active']);

$result = $stmt->fetchAll();

You can then execute the query a second time but with a different parameter value, in this case ‘closed’

$stm->execute(array['active']);

$result = $stmt->fetchAll();

Inserting data to your database

To insert data you will use the insert() method. It takes 2 parameters, the table name you are inserting to, and an associative array that maps the table field names to the values you’re inserting.  Also, as an added bonus, just as when you prepare a query, the values you pass into the insert() method get passed in a parameter place holders, bye bye SQL injection.

$db = Zend_Db::factory(Zend_Registry::get(’config’)->db);
$data = array(
‘promos_id’              => 3,
‘product_id’             => 11
);

$db->insert(’promo_products’, $data);
$lastId = $db->lastInsertId();

I emphasized the last line because the lastInsertId() function will return the auto generated primary key value from your last insert. If you write your queries in your data extration layer as classes, as you should be doing, then returning the primary key of the last row you just inserted can come in handy quite often.

Updating data

Updating a record in your database is very similar to inserting it. You will use the update() method which takes 3 parameters, the table name, an associative array that maps columns to NEW values, and an expressing for the WHERE clause of the query. The video will show the array being built directly inside the update() method, but I like to set it up ahead of time and then passing only the array variable, only to keep things cleaner when updating more than one field in the table.

$db = Zend_Db::factory(Zend_Registry::get(’config’)->db);
$data = array(
‘promo_name’            =>    ‘New name’,
‘promo_code’            =>    ‘New code’
);
$rowsAffected = $db->update(’promos’, $data, ‘promo_id =3′);

The update() method will return the number of rows that where affected by the query, in case you need to know that value.

Deleting rows

Deleting a row, or rows requires the use of the delet() method, and it takes the table name and an expression for the WHERE clause.

$db = Zend_Db::factory(Zend_Registry::get(’config’)->db);
$n = $db->delete(’order_detail’, ‘order_id = ‘.$order_id);

$n of course  being the number of rows deleted by the query.

And there you have it. Although this is a pretty simple overview of how to access your database through the Zend methods, I hope it still serves as a good tool for developers trying to get their feet wet in this environment. Once you become familiar with how each component behaves things become second nature as I’m sure they have been with any other tool and skill set you’ve added your development toolbelt.

$100 off Zend Studio for your time

// May 19th, 2009 // 1 Comment » // Zend Framework

email-survey-100off-siderailI’ve been using the Zend Framework for several months now, it started with about 4 hours of hair pulling, 3 hours of cursing and who knows how many hours of puring myself over the documentation, which in my opinion leaves a lot to be desired (hint, hint, Zend). Thankfully now I have a good grasp of it and I’ve developed a full online ordering portal for the company I work for, and I am in the middle of rewriting the current company’s main website.

Through the entire process for these 2 projects I switched over from Dreamweaver to using the Zend Studio IDE, and I love it. And now Zend is giving you at least $100 off Zend Studio if you take a survey, that in their words will:

…collect information about your PHP development and production environments, your PHP IDE usage and the importance of some IDE features. It should about 5 minutes of your time to answer the questions.  Your coupon code for use on the Zend online store as well as the current aggregate survey results will be available to you at the end of the survey.

Sounds pretty good to me, so get to it everyone.