Nowadays, everything is turning into a web application. Even simple websites have a mobile app relying on a REST Api. Web applications are accessible everywhere – on a laptop, desktop, tablet, mobile, and recently on wearable devices like smartwatches. Everything is becoming smaller and faster – front ends are becoming separated from back ends, and only communicate with the server through APIs.
What will we be building?
In this series, we are going to create a photo uploading app. For the front-end, we will use EmberJs and Foundation 5. EmberJs is a front-end framework featuring good integration with REST Apis. Foundation 5 will help us make a fast prototype of our front end. For hosting, we will use Heroku’s free tier (for more information about PHP on Heroku, see here). For the back-end, we will use Laravel. The source code will be available per-part, and in final shape in the final part of this series. You can download the code for part 1 here.
Let’s get started
A good way to start a new project in PHP is using Vagrant. Vagrant gives us the space to experiment a lot from project to project. I can have different PHP versions if I want with Apache for one project, Nginx for another. If something goes bad, I revert all my work and simply vagrant up
after that – and I never pollute my host operating system with various other installations.
The easiest way to get started is by following this quick tip, which will take you through a fast installation process and show you a working Laravel app in a matter of minutes so you can start hacking away. If you’re still not convinced why you should use Homestead and Vagrant, see here.
My Homestead.yaml looks like this.
Now that the box is running we have have to install Laravel. Firstly, lets use ssh to make a connection with the box.
vagrant ssh
Then navigate to the folder that will host our app.
cd Code
Here we need to download Laravel and then install the dependencies with Composer.
git clone https://github.com/laravel/laravel Laravel
cd Laravel
composer install
After Composer has finished installing all the packages, test in the browser by searching for localhost:8000 . If you have done everything right you will see this:
The files of the sample app are now available both inside the Vagrant VM and in your host operating system for editing with your favorite IDE.
Heroku
The below actions are all executed inside the VM, while logged in with vagrant ssh
unless stated otherwise. For a more detailed overview of Heroku on Vagrant and installing of addons, see this post, otherwise, see below.
If you don’t already have an account on Heroku, create one by following this link and download the Heroku Toolbelt. This is a client cli that simplifies our work with Heroku. We can install addons from this cli, create new projects and with the help of git we can also push every change. After creating an account on Heroku and installing Heroku Toolbelt you have to log in to start using it.
heroku login
After executing this command, we have a connection with Heroku. Now we can start creating a new project there.
To start using Laravel on Heroku we need to do some small changes. First, create a file and name it Procfile
. Add this line inside that file.
web: vendor/bin/heroku-php-apache2 public
This is a configuration file. Heroku needs it to know what it is dealing with. With this, we specified PHP and Apache. We can also use python, java, ruby, scala and more . When installing Heroku Toolbelt, Foreman is installed too. It is used for executing Procfiles locally, helping you maintain dev/prod parity. If you are curios as to what else a Procfile can do, follow this link from the official Heroku documentation.
If you’d like to use Nginx instead, see this post.
Execute these commands one by one in Laravel’s folder
git init
git add .
git commit -m "initing"
The second step is to remove the Composer.lock
from .gitignore
. After we are finished with git, let’s go back to Heroku.
heroku create
This creates a new project on Heroku.
git push heroku master
This will push everything to Heroku. Let’s test it. If everything goes well then we will see the Laravel logo we also saw when we tested it on Homestead Improved.
If you have problems with the rsa keys then read this article. If you want to know more about PHP on Heroku, see here and here.
Installing front-end packages
We’ll use Bower for front-end package installation . You are free to use anything you want, even downloading as zip from Github or from official pages. Navigate to the public folder in the Laravel folder.
cd public
There’s no need to install Bower because Homestead comes with nodeJs, npm and Bower pre-installed.
bower init
Then install the packages: Foundation 5, EmberJs and Ember Data. Ember data is a library used by Ember and is stand-alone. It will help us with the REST Api as a Rest Adapter.
bower install --save zurb/bower-foundation components/ember components/ember-data
Bower has installed everything for us, including all the dependencies.
Front-end skeleton
Lets start building the fundamentals of our project. Bower has installed the dependencies and put them in bower_components
. We also need a folder to put our static files in. Create a folder called static
in the public directory. Then create three folders inside: js
, css
and img
. In the js
folder create an app.js
file and in the css
folder, a style.css
file.
The first thing I always do when starting a new project with Laravel is to generate a key for secure password hashing.
php artisan key:generate
Create a new view in app/views
. Call it index.php
. This will be the landing page. We need to import all the javascript libraries and the styles inside that file.
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Webapp with EmberJs and Laravel4</title>
<link rel="stylesheet" href="/bower_components/foundation/css/foundation.css" />
<link rel="stylesheet" href="/static/css/style.css" />
</head>
<body>
<h1>A blank app</h1>
<script src="/bower_components/jquery/dist/jquery.js"></script>
<script src="/bower_components/foundation/js/foundation.min.js"></script>
<script src="/bower_components/handlebars/handlebars.js"></script>
<script src="/bower_components/ember/ember.js"></script>
<script src="/static/js/app.js"></script>
<script>
$(document).foundation();
</script>
</body>
</html>
This is the skeleton of the view – we can build from that. This is an one-page app which makes this file the only view in the entire application. Everything that we are going to build with Ember will be only in this file.
To use the index.php
view we have also to change the routes.php
file located inside the app
folder. Change the file to this:
Route::get('/', function()
{
return View::make('index');
});
Test it in your browser. Open localhost:8000
. A blank page with a title will appear. If we look at the inspector (ctrl+shift+i), there are no errors. Every file loads without problems. Upload all the changes to Heroku and see if it works there.
git add .
git commit -m "testing"
git push heroku master
Database configuration
Database configuration with Laravel is easy when dealing with different environments. We have to configure it in a way that works both on Homestead and on Heroku. On Heroku, Postgresql is not installed when the app is created, so we have to install it using the toolbelt. This addon does not require you to have a credit card:
heroku addons:add heroku-postgresql
In /app/config/database.php
change the default key to point to postgres.
'default' => 'pgsql',
Different config values are used for Postgres on Heroku and on Homestead. So how can these values be used in each case? From the original quick tip, we know the default Postgres port is 54320 and the user/pass combination for our development environment is homestead
/secret
.
We have to change the values for the production environment (Heroku, in this case).
Create a new folder called production
inside /app/config
. Copy the database.php
located in /app/config/local
and put it in the production config folder. Also put a copy inside the testing
folder. When you want to test your application, you have to configure the database for that environment, too. Laravel stores the configurations for Homestead by default in the local/database.php
folder.
Heroku stores the configuration of postgres as an environment variable. In the end, the file should look something like this.
<?php
$url = parse_url(getenv("DATABASE_URL")); // Get the environment variable
// and return it as an array
return array(
'connections' => array(
'mysql' => array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'homestead',
'username' => 'homestead',
'password' => 'secret',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
'pgsql' => array(
'driver' => 'pgsql',
'host' => $url["host"],
'database' => substr($url["path"], 1),
'username' => $url["user"],
'password' => $url["pass"],
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
),
),
);
Now the psql is ready to be filled with data by using migration and seeders. It is easier to maintain the code and make some changes using migration.
php artisan migrate:make create_users_table
A file will be created inside /app/database/migrations
. Add this Schema inside the up
method:
public function up()
{
Schema::create('users', function($table)
{
$table->increments('id');
$table->string('username');
$table->string('password');
$table->timestamps();
});
}
Also add this line inside the ‘down’ method:
public function down()
{
Schema::dropIfExists('users');
}
Artisan is a nice tool for cutting down development time. Migrations and seeders are just a bit of artisan magic.
php artisan migrate
This will execute the up
method on every migration file and creates the schema defined inside that method. On the other hand, php artisan migrate:reset
will execute the down
method and in most cases will revert all the changes that the up
method did. If you create a schema with the up
method, revert everything in the down
method.
The database now has a table called users
with a simple structure. Using the Seeders the database will be filled with data. After all, it’s better to have the data in the database by running one command than doing it manually every time the database changes.
Create UserTableSeeder.php
inside /app/database/seeds/
folder.
/* /app/database/seeds/UserTableSeeder.php */
class UserTableSeeder extends Seeder {
public function run()
{
Eloquent::unguard();
DB::table('users')->delete();
User::create(array(
'username' => 'foo',
'password' => Hash::make('password')
));
}
}
A seeder class has to extend the Seeder
class. Also, add this code inside /app/database/seed/DatabaseSeeder.php
because artisan doesn’t include custom files when running php artisan db:seed
. Instead, you have to use php artisan db:seed --class=UserTableSeeder
to use that particular class. I prefer to run php artisan db:seed
and let the DatabaseSeeder
do all the work.
/* /app/database/seeds/DatabaseSeeder.php */
class DatabaseSeeder extends Seeder {
public function run()
{
$this->call('UserTableSeeder');
}
}
This only adds one user inside the users
table. More users are needed for testing an application. We’ll handle this in part 2.
After inserting this snippet inside DatabaseSeeder.php
located in /app/database/seeds
, run the following command:
php artisan db:seed
A new row with our values has been created inside the users
table.
Heroku again
We have a database with a simple table on Homestead. But can these changes be made on Heroku? Use git to push the code online and find out.
git add .
git commit -m "adding database"
git push heroku master
Afterwards execute artisan on Heroku.
heroku run php artisan migrate
heroku run php artisan db:seed
Put heroku run
before any php/artisan command and it will work. Since this environment is in production mode, a question will appear on the screen. Hit enter and the users table will be created and seeded. If you have more seeders and migration files, the question would appear more often.
Wrapping up
In this article, we’ve built a skeleton for our application. It is now running in our local environment and on Heroku. In a situation where you deal with local development and cloud development, you can spend a significant amount of time dealing with configurations and being on the same page with two different environments. Next, we will finish creating the database. We’ll be creating some seeders with a fake data generator, and we’ll use a filesystem library to deal with local files. Stay tuned!