Cian Gallagher
Software Engineer

Building your own MVC Framework in PHP (Part 3)

Posted on Wednesday 2nd July 2014

Building your own MVC Framework in PHP (Part 3)

Hello, I'm back again with the 3rd installation of my MVC Framework in PHP series, again apologies that it took so long! Now without further ado, let's get straight into it!

We left of last time having created our index page view.
mvc3_1.png

What I'm going to show you today is how to render an existing page chosen, as well as start with styling our pages with bootstrap and get it looking like a real site. To start, we're going to need to open our Init.php file in our /libs folder. Your file should more or less look the same as last time as so:

class Init{
   public function __construct(){
       $url = isset($_GET['url']) ? $_GET['url'] : null;
       $url = rtrim($url, '/');
       $url = explode('/', $url);

		if(empty($url[0])){
			require_once BASE_PATH . '/controllers/index.php';
			$index = new Index();
			$index->index();
			return false;
		}
   }
}

What we're going to do is check to see if a controller exists from the URL specified by the user. If it does exist we're going to require that file so we can then instantiate it. So right after our previous if statement we are going to write:
// Check if page exists
$file = BASE_PATH . '/controllers/' . $url[0] . '.php';

if(file_exists($file)){
   // If it does, require it, and instantiate it
   require_once $file;
   $controller = new $url[0];
} else {
  // Log an error to user
}

As stated, this will check to see if the file exists, if it does we require in that file, and then instantiate it for use. The important thing now though, is our else. If no such file exists we need to log an error to the user acknowledging this fact. We'll come back to our Init.php file in a moment, let's go and make an error controller.

Go to our controllers/ folder, and create a file called error.php. The structure of the file is going to look much the same as our previous controller, except for a minor difference. We're going to pass in an argument our error class constructor so we can render it to the page.
<?php

class Error extends Controller{

	public function __construct($error){
		parent::__construct();
		$this->view->errors = array($error);
	}

	public function index(){
		$this->view->render('error/index');
	}
}

Now, same as before go to your views folder, and create a new folder called error and inside it a file index.php. Within our index.php we're going to check if our errors array has been set, if it has we then render our errors to the page for the user to see.
<h3>Error Page</h3>
			<br>
		<?php
			if(isset($this->errors)){
				foreach ($this->errors as $key => $er) {
					?>
					<p id="error<?=$key;?>"><?php echo $er; ?></p>
					<br>
					<?php	
				}
			}
		?>

As you will see later when we test this class, if a user were to try to visit a URL that does not have a file associated with it, they will be routed to our error controller, and displayed an error accordingly. So let's go back to our Init.php to test this out.

Outside of our constructor we are going to create a method called init_error to test. It will take a string variable as argument, require our error controller, instantiated our object and then render it. It will look like this:
private function init_error($errors){
		require_once BASE_PATH . '/controllers/error.php';
		$error = new Error($errors);
		$error->index();
		return false;
	}

Back in our constructor we can now modify the last if / else statement we made. To explain what this does: After we instantiate our object we want to check if the URL is attempting to route to a method within the specified class .It could be something like http://ciangallagher.net/aboutme/myname which might return my name as a string as an example. The full code looks like this:
if(file_exists($file)){
		// Require file
		require_once $file;
		// Instantiate class
		$controller = new $url[0];

		// Check if method is set
		if(isset($url[2])){
			if(method_exists($controller, $url[1])){
				// Instantiate class, with specified method if it does exist
				$controller->{$url[1]}($url[2]);
			} else {
				$this->init_error('Method Does not exist');
			}
		} else {
			if(isset($url[1])){
				if(method_exists($controller, $url[1])){
					$controller->{$url[1]}();
				} else {
					$this->init_error('Method Does not Exist');
				}
			} else {
				// Render to view
				$controller->index();
			}
		}
	} else {
		// Log error to use
		$this->init_error('File does not exist');
	}

So now when I try to go to an invalid URL I will see this:
mvc3_2.png

The same for an invalid method:
mvc3_3.png

Now I think it's time we started added some styles to our site so we can actually start making it look like a website. The first thing you're going to need to do is download the latest version of Bootstrap. As of writing that is version v3.2.0. It can be found here: http://getbootstrap.com/getting-started/. After you've done this, it's time to change up our folder structure to accommodate for these changes. After you've donwloaded bootstrap, extract it, and you should see 3 folders they are your fonts, css, and js.

In your public folder of your site (which should currently be empty) i want you to make 3 new folders called css, js, images and fonts. It should look like this:
mvc3_4.png

All we have to do now is extract our bootstrap files accordingly into their obvious folders `css -> css` etc. After you've done this we're going to our config folder and create a file within called config.php. Within config we just need to define a base URL that can be used across the site (this can be changed as needed on live/test instances.) mine will look like this, yours may differ depending on your path.
<?php

//define base URL
define('URL', 'http://localhost/basic_mvc/');

Also, don't forget to include this in your root index file, otherwise you won't be able to use it! Now with that done, let's go to our header.php and start adding our styles. We'll start with adding our bootstrap.css. As you can see we're using our defined URL as our path and then specify the file and location.
<!DOCTYPE html>
<html>
<head>
	<title>MVC</title>
	<link rel="stylesheet" type="text/css" href="<?php echo URL . 'public/css/bootstrap.css'; ?>">
</head>

In our footer.php we will also include Bootstraps js file and jQuery from Googles CDN.
        <script type="text/javascript" src="<?php echo URL . '/public/js/bootstrap.min.js'; ?>"></script>
	<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
	</body>
</html>

Now let's go back to our header.php file and using bootstraps pre-defined mark-up http://getbootstrap.com/components/#navbar we can make ourselves a navigation bar. The full code for the header.php will look like this:
<!DOCTYPE html>
<html>
<head>
	<title>MVC</title>
	<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
	<link rel="stylesheet" type="text/css" href="<?php echo URL . 'public/css/style.css'; ?>">
	<link rel="stylesheet" type="text/css" href="<?php echo URL . 'public/css/bootstrap.min.css'; ?>">
</head>
<body>
	<br>
<!-- Start page container -->
<div class="container">
<nav class="navbar navbar-default" role="navigation">
  <div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">MyMVC</a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active"><a href="<?php echo URL;?>index">Home</a></li>
        <li><a href="<?php echo URL;?>about">About</a></li>
      </ul>
      <form class="navbar-form navbar-right" role="search">
        <div class="form-group">
          <input type="text" class="form-control" placeholder="Search">
        </div>
        <button type="submit" class="btn btn-default">Submit</button>
      </form>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>

And look at that! We can now navigate between our pages, and it's starting to look more like a site!

mvc3_5.png

mvc3_6.png

Well enough writing for one day, i will hopefully be back sooner with Part 4. Check back soon! The full source code is also available on github, just follow the link below.

Part 2: https://ciangallagher.net/#post4

Github Source: https://github.com/Cian911/phpmvc-scratch



Building your own MVC Framework in PHP (Part 2)

Posted on Friday 11th April 2014

Building your own MVC Framework in PHP (Part 2)

Welcome back! Sorry it's been awhile, but let's get straight back into it!

Last time, we left off with our initial main index.php file in our Controllers folder. Let's take a step forward and go to our libs folder which we created at the start, and let's create a file called init.php within the folder.

mvc2_1.png

Next we're going to create a class from it.

 class init{
      public function __construct(){
         
      }
 }

What we're doing here is calling our init class's constructor. So when the init class get's eventually called, any logic within the constructor will get called as well.

So, the first thing we are going to do within our constructor is check to see whether there is a URL set. To make it simple we'll do start to do this with a Ternary Operator and then trimming the url, and finally exploding it. The print_r(); statement will be used once we require the file in to see what are URL is doing.
$url = isset($_GET['url']) ? $_GET['url'] : null;
$url = rtrim($url, '/');
$url = explode('/', $url);

print_r($url);

Next we will go back to the index.php in our main directory. Here we're going to define a base path for our entire directory to follow from and then require in our necessary library files from our /libs folder, and then instantiate our init.php file. The file at this stage should look like this:
<?php

// Define our base dirctory path
define('BASE_PATH', dirname(realpath(__FILE__)));

require_once BASE_PATH . '/libs/Init.php';

$init = new Init();

Edit* - After some discussion and comments I have been made aware of some flaws and some better practices to implement into this series. As such with the example above, it is far more prudent to use an autoloader, which is a rather handy function in PHP, to autoload our required classes into our application:

Note: - You can use either example really to load in your class files, but the autoload example below would be considered more practical.
<?php

define('BASE_PATH', dirname(realpath(__FILE__)));

function __autoload($class){
   // This will auto load in all our files from our given lib
   require_once BASE_PATH . "/libs/$class.php";
}

Now if we go back to our localhost we can start playing around with our URL. Th real beauty of this structure should start to be making some sense now. What we'll soon see and be able to do is that we can instantiate any defined class we wish and even pass arguments to methods, all from the URL.

mvc2_2.png

Now, what we're going to do is create a header.php and footer.php in our /views folder. Shouldn't matter what they contain at the moment, just your basic mark-up to denote head, title, body etc. The important thing comes next. Go back to our /libs folder and and create a file called View.php. This is going to be the class which contains the method that will let us render our pages to the user. It should look like as follows:
<?php

class View{

	public function render($name){
		require BASE_PATH . '/views/header.php';
		require BASE_PATH . '/views/' . $name .'.php';
		require BASE_PATH . '/views/footer.php';
	}

}

As you can see, we've made a function that will form an integral part of our framework. We load the head and footer in as required, then we can specify the file we want to load which displays our main page content. Next we will go and create another file in our /libs and call it Controller.php which will be our main controller that all other controllers will extend from.
<?php

class Controller{
        
        protected $view;

	public function __construct(){
		$this->view = new View();
	}
}

As you can see from from our constructor, we're instantiating our view object which we just created. Now at this point it's important to remember to require in the library files we just created in our index.php file in main directory. Now let's go back to our index.php (a lot of index's I know! Don't worry I'll rename the naming conventions next time round!) file held within our controllers folder so we can make some modifications to it. What the file should look like at the moment is this:
class Index{
  public function __construct(){
    echo 'We are in Index';
  }
}

What we are going to change it to, is this:
class Index extends Controller{

	public function __construct(){
		parent::__construct();
	}

	public function index(){
		$this->view->render('index/index');
	}
}

Now, let me explain. What we've done here now is extend this class from our main controller which we created a few moments ago. In our constructor, we've declared a static function that essentially means we want to use our parent objects constructor, i.e we want to use the View object we created! The next method will make more sense in a moment, but in essence what it is doing is rendering the view page we want to display, now let's create that.

Go to your /views folder, inside of here create another folder, yes folder and call it simple index. Then go into that folder called index you've just created, and create a file and call it index.php. Open the file and for testing purposes simpke but in some simple mark-up.
<h1>I am the Index page!</h1>

For clarification, you're folder should look something like this at the moment.

mvc2_3.png

Finally we're going to navigate back to our Init.php file in our /libs folder ,and we're going to check if the file exists, and if so, load it in! So in our contructor again in our init.php file, just after we've exploded our URL we're going to perform a check:
if(empty($url[0])){
	require BASE_PATH . '/controllers/index.php';
	$index = new Index();
	$index->index();
	return false;
}

This checks to see if the URL is empty, (in other words we are choosing the default landing page that the user will see when they navigate to your URL.) and if it is then require our index page and render it, and if all goes well we should see this!

mvc2_4.png

Ok, I think that's enough writing for one day. I hope to not be as long with releasing part 3 as I was with part 2. In the mean time i will upload each iteration of the framework I do here to my Github so you can all take a look at the code in full after each tutorial. I'll update this post again when I've done it.

Part 1: https://ciangallagher.net/#post2

Part 3: https://ciangallagher.net/#post5

Source Code: https://github.com/Cian911/phpmvc-scratch



Create your own Twitter Bot

Posted on Sunday 5th January 2014

Create your own Twitter Bot

Today i'm going to show you how to make a bot in twitter from scratch using PHP. The aim of this is for educational purposely only, although i have no doubt in my mind someone will make something novel out of it (for want of a more appropriate term!).

First things first, you will need a twitter account. Obviously. But more importantly you will need a developer account which you can get or upgrade your current account to here: https://dev.twitter.com/
You will also need the following files which can be found on my github page.

twit1.png

From there you will need to sign in form the top right hand corner. Then go to your application and create new application as so.

twit2.png

You will then be directed to a page to name and create your new application. Enter the details you want accordingly (you must currently have a live website to test the script on. If you don't you can try a free hosting account from here: http://www.000webhost.com/ a good starting point for beginners) and create your new twitter application. You will then see a page like this, with actual text mind you and not shoddy black lines drawn in paint!

twit3.png

At this point what you'll want to do is open your favorite IDE or text editor, mine is Sublime Text 2 if you must know. Now using our files we downloaded at the start you should see tmhOAuth.php and cacert.pem. What we need to to is create a new directory and place both files within it. The we are going to make a new PHP file, call yours whatever you wish, in my case i named mine websummit_bot.php. The next thing we are going to do is write some code! Let\'s make a class and include our tmhOAuth.php file.

<?php

# Enable error reporting
error_reporting(E_ALL);

class WebSummitBot{
	
	public function __construct(){

		# Require twitter auth file
		require 'tmhOAuth.php';

		# Use the data from http://dev.twitter.com/apps to fill out this info
		# Notice the slight name difference in the last two items)

		$connection = new tmhOAuth(array(
		  	'consumer_key' => '', 								# Your consumer key
			'consumer_secret' => '', 		# Your consumer secret
			'user_token' => '', 		# Access token
			'user_secret' => '' 			# Access token secret
		));
        }
}

?>

Then, let\'s instantiate our tmhOAuth class ,and add in our keys as provided on the twitter developer page. Next, we are going to create an array called paramenter, so we can pass it into our get request later.
$parameters = array();

And then the following conditional statements:
                if(!isset($_GET['q'])){
			$parameters['q'] = "%23websummit";
		}

		if(!isset($_GET['result_type'])){
			$parameters['result_type'] = "recent";
		}

		if(!isset($_GET['count'])){
			$parameters['count'] = 25;
                }

Now, to explain our first condition checks to see if our query is not set, if its not, then we will append a query to our parameters array. In my case in using the #websummit. The next condition is that of our result type, if it\'s not set already, we want to add it and set it to get the most recent tweets. The last of course is that amount of tweets we want to retrieve. So what this will do is search twitter for tweets containing the #websummit and get the most recent 25 of them.

The next thing we want to do then is set our path to the api and the data format we want to send and receive our information in. In this case it's JSON (Javascript Object Notation).
                if ($_GET['twitter_path']) { $twitter_path = $_GET['twitter_path']; }  else {
			$twitter_path = '1.1/search/tweets.json';
		}

		$http_code = $connection->request('GET', $connection->url($twitter_path), $parameters);

And at last we want to see if we get a response, if we don't we want to know why.
if($http_code == 200){
			$response = $connection->response['response'];
			$data = json_decode($response, true);
			# Remove the code for printing the data for now
			$data = (array)$data;
			
			for($tweet_id = 0;$tweet_id < 24;$tweet_id++){
				$id = $data['statuses'][$tweet_id]['id'];

				# [0] in this case is going to be a variable that we can loop through
				# Here, we want to pass in the id of the tweet that we want to retweet

				$twitter_path = '1.1/statuses/retweet/'.$id.'.json';
				$http_code = $connection->request('POST', $connection->url($twitter_path));

				if($http_code == 200){
					$response = $connection->response['response'];
					echo '<br>Sent';
				} else {
					echo '<br />';
					echo "Error ID: ",$http_code, "<br>";
					echo "Error: ",$connection->response['error'], "<br>";
					echo 'Not Sent';
				}
			}

		} else {
			echo '<br />';
			echo "Error ID: ",$http_code, "<br>";
			echo "Error: ",$connection->response['error'], "<br>";
			echo 'Not Sent';
		}

If we get a good response, we will loop through the 25 tweets and re-tweet them form our own account, otherwise we will receive an error.

Although this is a small tutorial, i hope it can be the basis for you to follow on and create some exciting things with the twitter API.



Building your own MVC Framework in PHP (Part 1)

Posted on Sunday 3rd November 2013

Building your own MVC Framework in PHP (Part 1)

Hello, and welcome to the first in my series of developing your own MVC framework in PHP. Now to begin, i want to get it out of the way with my own simple explanation of what an MVC actually is, and more to the point how it works before we delve into the code. MVC stands for Model View Controller (as you have no doubt ascertained from a Google search!) which is in its simplest form, a design pattern and one which has taken the business of web development by storm in recent years.

The idea behind the MVC is simple enough your Model handles the data and your business logic. Now you may ask (i know i did), "what really is your business logic?". Simple put, your business logic is how data can be created, displayed, stored, and changed in your application or website.

The View then, is how your data is presented to the user in any format your so desire. Probably the easiest part now that i think of it.

Finally, the Controller is responsible for receiving user requests and calling your appropriate resources (classes, methods etc.).

mvc1_1.png

Now, you may like to know that this site https://ciangallagher.net was built by myself from scratch using an MVC structure i modeled and made my own by tutorials and examples i found across the web and various other mediums. So what im going to do is show you all how to make a very simple framework for yourself's that you should be able to do anything with.

Lets do it! Ok, first things first. File Structure

mvc1_2.png

As explained above, you can see we have our controllers, models, and views folders. Our public folder here is where we will be holding any Javascript, CSS, or image files that we'll be using on the site. Our libs folder is where the real magic happens. This is our core folder.

Now, let's begin coding! The first thing, which in my opinion is the real beauty of the MVC structure is its use of routing. Right from the get go we have clean and sexy URL's which is a huge advantage for SEO at the very beginning. First let's start with the [.htaccess] file which we will place in our main directory itself.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*) index.php?url=$1 [QSA,L]

Next we want to make another php file and call it index.php which we will also place in our main directory. In it we want to write the following:
$url = $_GET['url'];
echo $url;

It should give us something like this, and allow you to change the URL anyway you desire without having to infer any sort of extension like .html or .php

mvc1_3.png

Next we are going to make a file in our controllers folder and call it Index.php

Edit - Something that was pointed out to me in regards to PHP closing tags (a point which I found out the hard way!). A big thanks to reddit user https://www.reddit.com/user/SeerUD for pointing this out to me:

"You should never have closing PHP tags in a file that contains only PHP. The reason for this is pretty simple really, on top of it not being necessary anyway, it can lead to errors in your application. If you leave a space, or any other content in a PHP file after that closing PHP tag then you've just started output to the browser. That means headers have been sent and if you have a lot of extra processing to do you're going to be leaving your client with a big 'ol white screen for a long time too".

As such the following code examples have been amended to reflect this insight.
class Index{
  public function __contruct(){
    echo 'We are in Index!';
  }
}

Next, back in our index file in our main directory we're going to require the class from our URL.
 require '/controllers/' . $url . '.php';
 $url = Index(); 

Later on i'll show you how we can deal with error handling when a user puts in a class to the URL that doesn't exist. But for the moment i will leave you with that! Be sure to check back here or follow me on twitter http://twitter.com/Cian_911 for updates and more tutorials!

Part 2: https://ciangallagher.net/#post4



A Formal Introduction

Posted on Monday 14th October 2013

A Formal Introduction
Hello, and welcome to my blog.

For those of you unfamiliar with me, my name is Cian Gallagher and i am an aspiring web and applications developer currently finishing a computer science degree here in Dublin, Ireland where i am from.

This blog (which was built from the ground up by myself!) will be here to showcase some of the work i have done professionally and in my own time as well as to blog about things that interest me such as programming, gaming, and all things tech really!

Stick around, and expect a lot more to come. In the mean time please follow me on twitter!
http://twitter.com/cian_911