Zend 2 For Beginners Step 2

All right, guys. In response to the Zend 2 For Beginners post, I thought I’d carry on and show more on how not to be afraid of Zend 2.

If you find yourself frustrated with frameworks as I was a couple of years ago, don’t lose hope. A lot of the frameworks out there have evolved to the point where they’re very manageable. If you’re like me though, and want to do pure PHP on your own projects, no one is forcing you to do Zend. And no, using Zend doesn’t guarantee that everyone who will use it will be a better coder, or that your code will be cleaner, or faster. In fact, it takes 10 times more of the processing power to render out a zend call than a pure php call.

But, if you’re involved in working with others on Zend, I’m writing this to show you that anyone with a bit of programming knowledge can pick up Zend 2 and go with it. Simple.

Let’s start!

Here’s the structure you will need for the basic module. The bare essentials to just render out some text.

1
2
3
4
5
6
7
8
9
10
11
12
13
modules
|-- Articles
    |-- config
    |   |-- module.congif.php
    |-- src
    |   |-- Articles
    |       |-- Controller
    |           |-- IndexController.php
    |-- view
    |   |-- articles
    |       |-- index
    |           |-- index.phtml
    |-- Module.php

Don’t be scared. this is only 4 files if you look at it carefully. Yes, it’s a lot of folders, but it’s not a lot of code. Yes, clean PHP could do it in one file, but there is a lot more to worry about as far as keeping track of all of the including, etc.

So, now, let’s look at the first file: The Module.php off of the module root folder:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// /module/Articles/Module.php
// This line defines our namespace. The place where our module resides. Keep this the same name as our module.
namespace Articles;

// Name our class, obviously.
class Module
{
    // this is to load our configurations for routes, etc.
    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }
   
    // this it to load our source files (namely, our controllers).
    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ),
            ),
        );
    }
   
}

And that’s it. Basically, this file tells us to load our module configuration and autoload any controller files we may have.

The next step is to look at our config file.:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// /module/Articles/config/module.config.php
return array(
    'router' => array(
        'routes' => array(
            // this is going to be what we call our route. It's a good idea to keep it the same name as our "link"
            'articles' => array(
                // Yes, this time, were passing in an exact match for the route. No parameters, no trailing slashes, done.
                'type' => 'Literal',
                'options' => array(
                    // Finally, this is what the URL should say to access this route.
                    'route' => '/articles',
                    'defaults' => array(
                        // And of course, we define our default controller and action.
                        'controller' => 'Articles\Controller\Index',
                        'action' => 'index'
                    )
                )
            )
        )
    ),
    // Specify our controller shortcuts (from the controller above)
    'controllers' => array(
        'invokables' => array(
            'Articles\Controller\Index' => 'Articles\Controller\IndexController'
        )
    ),
    // and, finally, where to look for our main file when the /articles link is hit.
    'view_manager' => array(
        'template_map' => array(
            'articles/index/index' => __DIR__ . '/../view/articles/index/index.phtml'
        )
    )
   
);

Simply put, this code above will direct any calls that come in to the right logic in the code and the right template file to use when rendering.

Next, our Controller file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// /module/Articles/src/Articles/Controller/IndexController.php
// Our namespace to define module and usage
namespace Articles\Controller;

// load this for basic controller functionality
use Zend\Mvc\Controller\AbstractActionController;

// define our class for this Controller
class IndexController extends AbstractActionController
{
    // And... define our main action.
    public function indexAction()
    {
       
    }
}

And that’s it with this one. Basically, the route points to this controller to do any sort of logic, or business logic, and calculations before sending stuff to the template for rendering.

And last, but not least, our view file!!! Yay!

1
2
<!-- /module/Articles/view/articles/index/index.phtml -->
This is my Articles Index file.

That’s it. There really isn’t much to it. This view file will produce a comment of the location and some text that mentions that this is my article index file.

If you could resist through this tutorial and the previous one, you can pretty much build your own Zend 2 modules. Yes, there’s a lot more to learn about Zend, which I’ll slowly be covering in other posts, but for now, to get you started to understand how everything is pulled into Zend to render out some simple pages, this is all you need.

I’m also going to teach you how to load scripts and css files into the header. That’s going to be fun. And later than that, I will be covering AJAX calls and partials.

Don’t forget to remove the /articles route from your Application module. 😉

See you next time!

Zend 2 For Beginners

If you’ve kinda touched Zend in the past and have been scared off like me of the complexity and everything you had to learn about it, I would like to share my Zend 2 experience with you. I’m assuming you have Zend 2 already set up on your local (Zend Server or apache and a project already set up), based on their documentation here:

1
http://framework.zend.com/manual/2.0/en/user-guide/skeleton-application.html

Let’s begin, shall we?

First thing you will notice is the folder structure of the main Application module. It’s the only module in the whole site. Let’s start with that.

Whenever you hit your site url local.mysite.com, you get to see the Zend default index page which resides in the /module/Application/view/application/index/index.phtml folder/file. If you modify this page’s HTML code, you will notice changes whenever you refresh your page. Ok, so this is good. This means that this module works, Zend works, the whole Universe makes sense, for now.

Also notice another piece of information in the /module/Application/config/module.config.php file. This is your routing mechanism. This is an array for your routes. Notice the ‘home’ route. It basically says that if you hit the ‘/’ root site, load up the index action from the Application/Controller/Index controller. Standby. How does it know what this controller is? Scroll down below and notice the controllers array. It holds an array called invokables. Seems familiar? Basically, whatever route you have set up, is pointed to the right controller in here. Make sure you keep this in mind for adding additional routes in the application module, or any module later.

The first thing I did was to create additional routes that load other templates within the Application module. I wanted to create a route for /login. Just to have a login page. The thing about a login page is that it should be accessible from anywhere publicly, so I made it part of the Application module. Making it part of a Profile module, or Authentication module doesn’t make too much sense here since the page is a public page that anyone can access. I might do the same for the registration module.

So, first thing I did was created the route for my /logic link.

1
2
3
4
5
6
7
8
9
10
11
12
13
// /module/Application/config/module.config.php
...
'login' => array(
    'type' => 'Literal',
    'options' => array(
        'route' => '/login',
        'defaults' => array(
            'controller' => 'Application\Controller\Account',
            'action' => 'login-page'
        )
    )
),
...

It’s a Literal because it’s a direct link. I don’t need to pass anything else other than an absolute check for /login in the URL.

Another thing to notice is the defaults. So, basically, this says to point to somewhere and load something by default if the route /login is matched. Don’t rush too fast. You need to add three more things.

1. Insert a pointer to your controllers invokables array:

1
2
3
4
5
6
7
8
9
// /module/Application/config/module.config.php
...
'controllers' => array(
    'invokables' => array(
        'Application\Controller\Index' => 'Application\Controller\IndexController',
        'Application\Controller\Account' => 'Application\Controller\AccountController'
    ),
),
...

2. Set up a new Controller in the /module/Application/src/Application/Controller/ folder. Keep the name as the invokable above: AccountController.php. Add the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// /module/Application/src/Application/Controller/AccountController.php

// This is to let the application know where this controller is located.
namespace Application\Controller;

// Default Zend Abstract Controller
use Zend\Mvc\Controller\AbstractActionController;

// Your Controller Class (Name should follow the same convention as above). This also extends the default Abstract Controller.
class AccountController extends AbstractActionController
{
    // Keep the name as in your route's action, replacing the dash with uppercase.
    // login-page becomes loginPage, and add Action so zend knows this is the action for the specified route.
    public function loginPageAction() {
        // Your logic code here.        
    }

}

And now, for the template that you’ll be using. By default, Zend will look for the template based on the action specified in your routes. So, it will look for this file: /module/Application/view/application/account/login-page.phtml

Notice the login-page naming convention. It’s good to keep this the same to avoid further confusion. If this page is blank, you will only see the default Zend header and footer.

And now, load your page. If it didn’t work, go back through the steps, and if it still doesn’t work, leave a comment on how you fixed it.

** Next step **

Let’s add some dynamic behavior. Let’s pass in some variables and play around with getting route information from Zend itself.

One thing to notice here is that our routes will change slightly.

Add the below code under your previous “login” route.

1
2
3
4
5
6
7
8
9
10
11
12
13
// /module/Application/config/module.config.php
...
'articles' => array(
    'type' => 'Segment',
    'options' => array(
        'route' => '/articles[/][:id]',
        'defaults' => array(
            'controller' => 'Application\Controller\Account',
            'action' => 'test-with-param'
        )
    )
),
...

We will call this the /articles link, as in news, or blog posts. It could be whatever you wanted, of course, but for now, we’ll play with articles.

Notice our “Literal” has become a “Segment” route. This means that the route will be broken up into little pieces and dynamic stuff will be added to it.

This could be moved into an “Articles” module, which we will later, but for now, we’ll keep it as part of our app, since this, just like the login page, is going to be accessed on our main site.

We don’t need to add anything to our controllers invokables, because we’re calling the same controller. let’s look at our AccountController.php file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// /module/Application/src/Application/Controller/AccountController.php
...
public function showArticlesAction() {
    $routeMatch = $this->getEvent()->getRouteMatch();
    $params = $routeMatch->getParams();
   
    $query = $this->params()->fromQuery();
   
    return array(
        'params' => $params,
        'query' => $query
    );
}
...

Notice something not right here? That’s right, we’re putting article stuff in our AccountController.php Controller file. Articles have nothing to do with accounts, so, we should probably move this function out of here. For now, just to write some spaghetti code that we will learn to refactor later, let’s leave it here.

Notice what’s happening in this controller action. We’re setting some variables that we return in an array. This array will contain a key / value pair that coincidentally have the same name. The keys will become variables in our template that we get to write out, or loop through. Example: the ‘params’ key will become a variable “$params” for the template to use. Let’s see how that looks.

1
2
3
4
5
6
7
8
9
// /module/Application/view/application/account/show-articles.phtml
<div>
    Test With Param
   
    <pre>
        <?php print_r($params); ?>
        <?php print_r($query); ?>
    </pre>
</div>

And when we hit the url: /articles, we should see a nicely formatted list of our variables.

Next post, I will go through the process of moving this feature into our very own Article module.

Comments always welcomed.

Magento Sucks

Some might think that I want some attention, or have become a grumpy old man. Considering my birthday is tomorrow, turning 36 might be as close to a grumpy old man as I can get.

I want to make some things clear. I have nothing against people using these awesome tools coming out every six months, only to be used for a short period of time. I just want to share my experiences in the 12+ years I’ve been developing. Also considering the fact that I’ve been programming since the age of 11, self taught in basic, I think I understand a few things about writing code.

For the same reason that Apple became the number one company in the world, I like simplicity. Even when it comes to programming. Just because I’m a programmer doesn’t mean that I have to be some rocket scientist that only a few can understand.

Good programmers can write complex code that intertwines on itself in amazing loops and conditionals that will make even the smartest of people look at the code like a dog looks at someone whistling. Great programmers will write code that programmers at any level will easily understand.

This reminds me of the time I picked up Magento. What a convoluted piece of crap! I’m not talking about the basic use of pulling it out of the box and creating a template, but I’m talking about trying to revert from Enterprise back to the Community edition. I mean, holy crap! My head spun around for over 3 months trying to duplicate all of the functionality that already existed in Enterprise. Don’t ask me why business wanted to do that. They’re the ones that think they understand the product and sell it like that to their clients.

I vowed to never touch Magento ever again. Unless, someone needs a simple out of the box solution with a pre-purchased tempalte, there are other programs out there that can do everything much simpler. Presta-shop, wordpress, even weebly has introduced an ecommerce solution for moms and pops.

I like the idea behind Magento and its flexibility, but there’s no way you can build something so flexible to allow for everything you ever wanted. There are workarounds around it, and even then, you still have to revert back to simple PHP in many cases. If it was so flexible that you could do anything, well, then, you’d have PHP. So, why the need of a framework?

From my understanding, Magento was built in two weeks by an offshore Russian or Ukranian who worked nights and weekends to get this magestic piece of crap out to the market… And boy, was it buggy… Many revisions later, it’s still a monster that no normal developer wants to touch. For those that do, best of luck to you. You’re obviously MUCH more intelligent than someone like me.

At one point, the company that I worked for even had a project where the only reason to use Magento was to store user information. Everything was ignored, even the templating system. Everything was bootstrapped to render out custom template files outside of the working template folders. Talk about spreading butter with a chainsaw.

Basically, I’m never happy working in an environment where we start out with a framework, and in months we’re using custom code to run everything. Why not start fresh? Tabula Rasa! Clean slate. So much more control over what you do, and so much you can customize from the beginning.

So much abstraction in the programming world. I left the world of Physics because I wanted less abstraction and more reality based practical involvement and construction. Abstract thinking is just that. Abstract. It has its place in the world of physics and math. Engineering just doesn’t function on abstract ideas. You have to be precise and realistic, otherwise your building collapses.

I guess some programmers just like to be challenged for the sake of being challenged. Not this guy. I like keeping my brain functioning beyond the age of 50.

Let’s keep it real, folks!