Learn PHPixie in 30 Minutes

This small tutorial will get you started in developing with PHPixie in just 30 minutes. Actually if you have experience with any other PHP framework it will probably take much less. Hopefully you will see how simple, flexible and powerful this our pixie really is.

First follow the Download Instructions to install PHPixie via Composer.

Our little website
We will now create a small website for keeping track of fairies. We should be able to list fairies, view and add them. For that purpose we need to create a table with 3 columns: id, name and interests. You can create that table yourself, or use a MySQL dump file from https://github.com/dracony/PHPixie-Sample-App/blob/master/fairies.sql . PHPixie is a MVC framework, MVC standing for Model, View, Controller, all of which we will learn about in a while. As we need to create three pages to manage fairies it’s time to learn about Controllers.

Controllers and Routing
Controllers are the heart of your website, each controller represents a group of related pages, and each method inside a controller is one of those pages. Since all our pages are concerned with fairies we only need a single controller with three actions (pages). The most simple example would be this:

namespace App\Controller;

class Fairies extends \App\Page {

	//'index' is the default action
	public function action_index() {

		//The value of $this->response->body
		//Will be echoed to the user
		$this->response->body="This is the listing page";
	}

	public function action_view() {
		$this->response->body="You can view a single fairy on this page";
	}

	public function action_add() {
		$this->response->body="Here will be a form for adding fairies";
	}

}

When you visit a URL it is matched against a set of rules called Routes that decide which Controller and which Action will be called. We will only have a single route defined in our routes.php config file, it should like this:

return array(
	'default' => array('(/<controller>(/<action>(/<id>)))', array(

					//Make 'fairies' the default controller
					'controller' => 'fairies',

					//Default action
					'action' => 'index'
					)
				),
);

Which means that for example a URL like http://localhost/fairies/view/1 would trigger the action_view() inside the Fairies controller, and pass it and id parameter with the value of 1. The default action is defined to be index and the default controller is fairies, so visiting http://localhost/ is the same as http://localhost/fairies/index/ . You can add any amount of complex routes yourself to this file, a detailed explanation of how to do so is in our Routing Tutorial, but for now let’s start adding HTML to our pages, that is what Views are for.

Views
Views are basically PHP template files, you can pass variables to the view from the controller and them render the view when needed. The most simple example would be this:

public function action_index(){
	//Get the /assets/views/hello.php view
	$view = $this->pixie->view('hello');

	//Pass a variable to the view
	$view->message = 'hello';

	//Render the view and display it
	$this->response->body = $view->render();
}
<!-- $_() is a function that will escape and print a string. -->
<!-- It's the equivalent of "echo htmlentities($message)" -->
<h2><?php $_($message); ?></h2>

Notice the $pixie object that we used to get the view, you will encounter it quite frequently later on, especially whenever you access something. PHPixie doesn’t use static methods and properties, and discourages instantiating classes in random places, all global things are handled using the $pixie object, that is accessible almost everywhere.

Page layout and our first controller
The flaw with using a separate view for each page is that you may end up copying common layout like header and footer to every page, which is not usable at all. Instead it’s convenient to have on main view that defines the general layout, and include subtemplates into it. It’s very easy to achieve using the before() and after() methods of the Controller. The skeleton application has them already implemented, but let’s take a closer look at it.

namespace App;

class Page extends \PHPixie\Controller {

	//This is where we store our view
	protected $view;

	//This function will execute before each action
	//We will use it to initialize a common layout
	public function before() {

		//Here we reference the /assets/view/main.php view
		$this->view = $this->pixie->view('main');
	}

	//This function will execute after each action
	public function after() {
		//It will render the view template and output
		//the response to the user
		$this->response->body = $this->view->render();
	}

}

For our view we will use Twitters’ Bootstrap CSS, so that we don’t have to worry about styles.

<!DOCTYPE html>
<html>
	<head>
		<title>Fairies</title>
		<link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.2/css/bootstrap-combined.min.css" rel="stylesheet">
	</head>
	<body>
		<div class="container">
			<div class="span4 offset4">
				<h2>Fairies</h2>
				<!--
					Here we will include the file
					specified in the $subview
				 -->
				<?php include($subview.'.php');?>
			</div>
		</div>
	</body>
</html>

All our actual controller has to do now is pass a $subview parameter to the view to specify which page to render on each action, optionally it can also pass some additional variables, e.g the name of the fairy etc.

Setting up the database
Before we can manage the data inside the fairies table, we need to configure a connection to the database. All configuration files are inside the /assets/config folder, edit the db.php config file to suite your setup:

return array(
	'default' => array(
		'user'=>'root',
		'password' => '',
		'driver' => 'PDO',

		//We named our database 'pixies', if you called it
		//something else, just put that name instead.
		//'Connection' is required if you use the PDO driver
		'connection'=>'mysql:host=localhost;dbname=pixies',

		// 'db' and 'host' are required if you use Mysql driver
		'db' => 'pixies',
		'host'=>'localhost'
	)
);

Now let’s create a model for our fairies.

Models
A Model is a class that usually represents some entity, it may be a user, a post, a category, anything. In our case it will be a fairy. It takes a lot of code to make a model, you have to write methods for storing it’s data into the database, reading, deleting it, etc. Thankfully PHPixie will do all that for you using its ORM module that we already have installed via composer. All we have to do for transforming our fairies table into a model is this:

namespace App\Model;

//PHPixie will guess the name of the table
//from the class name
class Fairy extends \PHPixie\ORM\Model {

}

That is it! We don’t have to worry ourselves with database access anymore! It’s all just a piece of cake from now on. There is much more that ORM can do, but that’s all that we need for this tutorial, check out the ORM guide for more information.

Fairies Controller
Now that we have everything ready we can start working on managing out fairies. First let’s create a listing page to see all fairies that we have in our table:

namespace App\Controller;

class Fairies extends \App\Page {

	public function action_index() {

		//Include the list.php subtemplate
		$this->view->subview = 'list';

		//Find all fairies and pass them to the view
		//ORM takes care of that
		$this->view->fairies = $this->pixie->orm->get('fairy')->find_all();
	}
}

Wasn’t that simple? It only took 2 lines of actual code. Now we need to create a subview in /assets/views/list.php like this:

<table class="table table-striped">
	<thead>
		<tr>
			<th>#</th>
			<th>Name</th>
		</tr>
	</thead>
	<tbody>
		<!--
			Display the ID and name of each fairy
			And link to her page
		 -->
		<?php foreach($fairies as $fairy):?>
			<tr>
				<td><?php $_($fairy->id);?></td>
				<td>
					<a href="/fairies/view/<?php echo $fairy->id;?>">
						<?php $_($fairy->name);?>
					</a>
				</td>
			</tr>
		<?php endforeach;?>
	</tbody>
</table>
<!-- Link to fairy creation form -->
<a href="/fairies/add" class="btn btn-success">Add a new fairy</a>

Viewing a single fairy is also simple and very similar to the listing page, all we need to do is get her ID from the URL and find her by that ID.

namespace App\Controller;

class Fairies extends \App\Page {

	//... action_index() code ...//

	public function action_view() {

		//Show the single fairy page
		$this->view->subview = 'view';

		//Get the ID of the fairy from URL parameters
		$id = $this->request->param('id');

		//Find a fairy by ID and pass her to the view
		//ORM makes it very trivial too
		$this->view->fairy = $this->pixie->orm->get('fairy', $id);
	}

}

And the view, even simpler than the previous one:

<h3><?php echo $fairy->name;?></h3>
<p class="lead">
	<?php $_($fairy->interests);?>
</p>
<a href="/" class="btn btn-success">Back to the list of fairies</a>

Now for something a bit more complex, we have to be able to also add new fairies. It will take a bit more code to do that ( WHOLE 6 lines of code!!! =3 ), so this time let’s first look at the view:

<form method="POST">
	<fieldset>
		<legend>Add a new fairy</legend>
		<label>Name</label>
		<input name="name" type="text" placeholder="Type something…"/>
		<label>Interests</label>
		<div>
			<textarea name="interests"></textarea>
		</div>
		<button type="submit" class="btn btn-primary">Submit</button>
	</fieldset>
</form>

What we have here is a simple form that submits its data using the POST method back to the same page. The controller will have to check if the form is submitted and process it, otherwise it should just display it.

namespace App\Controller;

class Fairies extends \App\Page {

	//... action_index() code ...//

	//... action_view() code ...//

	public function action_add() {

		//If the HTTP method is 'POST'
		//it means that the form got submitted
		//and we should process it
		if ($this->request->method == 'POST') {

			//Create a new fairy
			$fairy = $this->pixie-> orm->get('fairy');

			//Set her name from the form POST data
			$fairy->name = $this->request->post('name');

			//Set her interests from the form POST data
			$fairy->interests = $this->request->post('interests');

			//Save her
			$fairy->save();

			//And redirect the user back to the list
			return $this->redirect('/');
		}

		//Show the form
		$this->view->subview = 'add';
	}

}

This is it! Now we can manage our fairies!

You can get the full source code for this tutorial on https://github.com/dracony/PHPixie-Sample-App/

Now let’s dive in for some more theory =)

The Big Picture
So here is how it all works:

  • A URL is tested against a set of Routes to find the appropriate Controller and Action to Run
  • Our Page Controller initializes the main view
  • An action is the Fairies Controller executes, retrieves some data and passes it into the View
  • The Page Controller renders the view and outputs it

One more important thing is the $this->pixie object. It’s the heart of the framework, its dependency container. All classes are instantiated inside it, and it acts as the global scope. You will also notice that PHPixie never uses any static methods nor properties, things like that are also stored inside the pixie. We encourage you to follow the same pattern for better testability of your application. Try placing static and global things inside the Pixie. You can add anything to it by editing the /classes/app/pixie.php:

namespace App;

class Pixie extends \PHPixie\Pixie {

	//This is how we enable PHPixie modules
	//after they are installed
	protected $modules = array(
		'db' => '\PHPixie\DB',
		'orm' => '\PHPixie\ORM'
	);

	//You can add whatever methods/properties
	//you want here
}

Start making it your own!
You’ve completed our little tutorial, now it’s time to delete the sample Models and Controllers and make something of your own. If you run into any problems, please let us know on the forums, and we will be sure to help you.

49 thoughts on “Learn PHPixie in 30 Minutes

  1. sunshine.by

    Should’nt it be action_view() instead of view_action() you mention after the second code snippet?

    Reply
    1. admin Post author

      Really? There was nothing borrowed from Kohana code-wise. The feel of phpixie 1 was ‘kohanish’ though. Phpixie 2 works totally different. Kohana doesnt have a DI container for example etc.

      Reply
  2. aldo

    Hi, I want to learn this framework but I have a big question:

    What happens when you want to upload your application to a server? I have to install the composer and all that stuff there?

    Reply
    1. admin Post author

      Well, you can run composer on your local computer, and upload just the code. There is no rel benefit from running composer on the server.
      If you have more questions just post them on the forum. It’s much easier to keep track of them there =)

      Reply
  3. Neu

    >> namespace App\Controller;

    Filename and path?

    >> Inside the controller
    >> public function action_index(){

    Filename and path?

    Reply
  4. Thor

    I’m getting Apache 500 errors since I’m having troubles with where I should locate Composer and the sample pixie app. Could you please clarify the folders where these should be extracted? Thanks.

    Reply
    1. admin Post author

      Well you should extract it so that the site points to the /web/ folder ofthe pixie installation. if you have any more problems please post them to the forums. It’s easier to communicate there.

      Reply
  5. kim

    Hi, this tutorials work nicely on my localhost. However when I upload it to my hosting Its giving an error

    [23-Sep-2013 01:49:39 America/Chicago] PHP Warning: include(/home/xxxx/public_html/beta/classes/App/Pixie.php) [function.include]: failed to open stream: No such file or directory in /home/bocil/public_html/beta/vendor/composer/ClassLoader.php on line 185
    [23-Sep-2013 01:49:39 America/Chicago] PHP Warning: include() [function.include]: Failed opening ‘/home/xxxx/public_html/beta/classes/App/Pixie.php’ for inclusion (include_path=’.:/usr/lib/php:/usr/local/lib/php’) in /home/xxxx/public_html/beta/vendor/composer/ClassLoader.php on line 185
    [23-Sep-2013 01:49:39 America/Chicago] PHP Fatal error: Class ‘App\Pixie’ not found in /home/xxxx/public_html/beta/php/index.php on line 7

    I already check and the pixie.php is there…
    Tried to login to forum to post it there, but something error on your forum. failed to login with google or twitter account

    Reply
    1. admin Post author

      make sure you have your files and folder in proper case e.g. classes/App/Pixie.php not classes/App/pixie.php or classes/app/Pixie.php

      Windows doesnt care about file name case, but linux is case sensitive

      Reply
      1. kim

        wow thanks for the fast reply.
        and yeah that’s works. Pretty sure it was Capitalize before
        love this framework simplicity. Thanks for making it

        Reply
  6. Patrick

    Hi – Thanks for the interesting tutorial.

    I have one Beginner-Question left – How do I sensefully organize and store my views?
    I mean in your example they are all in “\assets\views\…” what is ok with one Class.

    but if there are several Classes (fairies and trees for example) there would be two “list.php” in the same folder.
    So I thought maybe it is a good idea to store the views in Subfolders like “\assets\views\Fairies\list.php” and so on.

    I could extend the Page class with $this->viewFolder = get_class($this) and adding the Folder this way to the controllers which later inherit herefrom. But is that a good way?

    How would you handle this?

    Thanks and Well-Done Job so far…
    Pat

    Reply
  7. Pedar

    Hi,

    I think classes in the files “/classes/App/Controller/Fairies.php” and “/classes/app/page.php” must extend correctly. You may swap their mother classes.

    Reply
      1. Pedar

        I haven’t executed this tutorial yet by myself but I think in the “/classes/App/Controller/Fairies.php” file, you must use this line:

        class Fairies extends \PHPixie\Controller {

        instead of

        class Fairies extends \App\Page {

        Also for the “/classes/app/page.php”, shouldn’t you use this line

        class Page extends \App\Page {

        instead of

        class Page extends \PHPixie\Controller {?

        Reply
  8. djmg

    I’m trying to register in your forum but it doesnt give me the password[throws error connecting the site]. My question is related to your framework, I’m quite new to the php scene but for my master-thesis in a M.Ing. IT I’m programming a social network in HTML5, do you think your framework is ready for production? Could I have a any problems with security/performance issues with a (bit complex) database? For what I see it has what i need, ORM and Caché and e-mail modules.
    A part of that, I’ll use nginx instead of apache for the server, so no .htaccess[i know there's a way to translate htaccess to nginx style]. Can this give me also troubles?ç
    Also i want to ask if it’s based on PHP5.4 or is just php5.4 compatible.
    Thankyou.

    Reply
    1. admin Post author

      Which account did you ty to sign in with? I know Facebook sign in is working properly and Twitter sign in is glitchy sometimes. If you tell me which one you used I’ll fix it =)

      As for being producton ready, PHPixie is quite simple as you might’ve noticed =) So basically it’s as secure as you make it. The database uses prepared statements so SQL injectios won’t happen, but you may want to come up with some CSRF protection for your forms etc. Nginx should be fine, you’ll need something like this to rewrite URLs:

      location / {
      index index.php index.html;

      if (!-e $request_filename) {
      rewrite ^/(.*)$ /index.php?$1 last;
      }
      }

      And it’s fully compatible with PHP 5.4

      Reply
  9. Victor

    Hello! I find some errors in your tutorial. You must use echo $fairy->name instead $_($fairy->name). Other variable similarly

    Reply
  10. rifaideen

    when i run the tutorial it throws Class App\Controller\Pixie doesn’t exist
    what is the problem and i cannot access it directly from localhost

    Reply
    1. admin Post author

      check that the file and folder names all start from an uppercase, e.g. /App/Controller not /App/controller/

      Reply
  11. Eric

    Hi,

    First of all i dig a little bit in your framework and i like it alot! nice work imo.
    but… Yeah there is always a but ;) cant help it.

    In your module tutorial you explain it by example that is fine, but i miss something.
    I like to know how i can archieve `fat models skinny controllers`.
    For example my models dont always represent as a DB layer, so it wont extend a class.

    But i still want to use a module in the model class. is there something else that i have to extend so i get access the the Pixie Object, so i can call $this->pixie->{module}->{method}? or do i have to give Pixie object in the construct so access it?

    You probably know it better than me what to do? Thx for you reply already!

    Eric

    Reply
    1. admin Post author

      The simplest method would be to create your own Model manager. For example:
      1) Create an abstract class \App\Entity like this:

      namespace App;
      abstract class Entity{
          protected $pixie;
          public function __construct($pixie) {
              $this->pixie = $pixie;
          }
      }
      

      2) Create a namespace \App\Entity\ where you’ll put your entities that will also extend App\Entity base class
      3) Create an entity manager like this:

      namespace App;
      class EntityManager{
          protected $pixie;
          public function __construct($pixie) {
              $this->pixie = $pixie;
          }
          public function get($name) {
              $class = "\App\Entity\".ucfirst($name);
          }
      }
      

      4) Append your entity manager to your App\Pixie

      namespace App;
      class Pixie extends \PHPixie\Pixie{
         .....
         public $em;
        
         public function after_bootstrap() {
             $this->em = new \App\EntityManager($this);
         }
      }
      

      Now you will be able to load your entities via $this->pixie->em->get($class_name);

      Reply
  12. Eric

    Hi thx for your reply,

    Can you give me an account on the forum part of this website? i cant login with any of the given methods.
    This way i can be a part of using the framework.

    Eric

    Reply
    1. admin Post author

      Fixed the forum registration =) Thanks for noticing this.
      I’ve been moving the website to a new VPS and it seems something haven’t moved that smoothly =)

      Reply
    1. admin Post author

      as for “class Page extends \App\Page” it can’t work, since it would mean it is extending itself. \App\Page is an extended version of a basic \PHPixie\Controller that adds some templating support.
      By extending \App\Page the Fairies class is using those added features.

      If you wish to discuss this further, please post ont he forum =)

      Reply
  13. Doug

    I’m also having trouble signing up for your forum. I’ve worked through the tutorial but would like to ask a question or two. Thanks.

    Reply
  14. Doug

    I’d like to register for your forum but none of the methods seem to be working. I’ve gone through the tutorial and have a question or two. Thanks.

    Reply
      1. Doug

        I tried Twitter and Google. Nothing came up for OpenID. Sorry about the double post above–the browser had timed out and I didn’t think it was saved.

        Reply
  15. EllisGL


    //Get the /assets/views/hello.php view
    $view = $this->pixie->view('main');

    How the heck would this pull “hello.php” when it looks like it’s pulling ‘main.php’?

    Reply
  16. Matt

    Hello,

    PHPixie looks really great but I have trouble installing it on my WAMP configuration.

    I followed the Download Instructions and my files are located like this :
    C:\wamp\www\ is the root where I have all projects. I put composer.phar in it.
    In C:\wamp\www\myproject, I have assets/ classes/ vendor/ web/ composer.json composer.lock and README.md.
    I created a “myproject” vhost binding to “C:/wamp/www/myproject/”.

    When I try to reach http://myproject/web/index.php, I have “No route matched your request” error.
    When trying “http//myproject/hello/index/” it says “not found”.

    I tryed to follow Generq\al Instruction’s “Installing into a subfolder” but it still doesn’t work.
    Do you have any idea ?

    Reply
    1. admin Post author

      Your problem is that you should point your webserber to /phpixe/web/ not to /phpixie/, it doesn’t seem like you need to install into subfolder at all. If you have further problems please post on the forum, it’s easier to communicate there =)

      Reply
      1. oke11o

        Hello. I want to try Phpixie. It great framework. And i like it.
        But I want to ask. How add model with underscore in name? And uppercase symbol in name? Autoloader cat’n found it.
        I know, that I can use public property $table to help. But I want to use different name of model.

        Reply
  17. oke11o

    Hello. I want to try Phpixie. It great framework. And i like it.
    But I want to ask. How add model with underscore in name? And uppercase symbol in name? Autoloader cat’n found it.
    I know, that I can use public property $table to help. But I want to use different name of model.

    Reply
  18. Abhishek

    Admin,

    Greetings, I would appreciate a lot if you write steps to integrate google DATASTORE as DB in phpixie framework.

    Reply
    1. admin Post author

      Well, take a look at how database drivers are made for v3: https://github.com/phpixie/database

      Basically all you need is to create a custom Driver class (you can use MongoDB driver as example). There’s a lot to talk about here, so maybe make a forum thread instead =)

      Reply
  19. John Sereno

    I somehow have screwed up my sign-in. I had problems with my Ubuntu system and I lost a lot of stuff. Can you just delete me and I will try to recreate my sign-in. Sorry to use this here but there seems no other way for me to send a message.

    Reply
  20. Joe Emenaker

    If you have a chance, could you maybe put the starting and ending php tags in your examples? I just wasted 2+ hours trying to figure out why I was getting “Class App\Controller\Fairies doesn’t exist” errors when I tried even the most basic example. Including line numbers in your code samples (and having the line numbers start with 1) gives the impression that you’re posting the entire file, and not just the part between the php start/end tags.

    Reply
    1. admin Post author

      Well there are a lot of places where i just post a snippet. But i’ll add opening tags to places where i put an entire file. Closing tags on the other hand are not required and actually harmful =)

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>