This series is not intended to be for complete beginners. Basically, I assume that you are familiar with your personal development environment, you can set up a new Laravel project and get the project running in the browser.
You should have an environment that works right now. I personally work on an Apple MacBook. Due to other projects and special configurations, I rely on the installation and configuration of my software by brew, a package manager for macOS. But feel free to use Laravel Valet or anything else, you are comfortable with.
Due to my configuration, I'm gonna always refer to http://local.pingping.io:8080
. You might have something different. For instance, http://pingping.test
.
A side note: These are the services I'm currently using at the time of writing this post.
➜ services list
Name Status User Plist
redis started stefan.bauer /Users/stefan.bauer/Library/LaunchAgents/homebrew.mxcl.redis.plist
memcached started stefan.bauer /Users/stefan.bauer/Library/LaunchAgents/homebrew.mxcl.memcached.plist
php71 started stefan.bauer /Users/stefan.bauer/Library/LaunchAgents/homebrew.mxcl.php71.plist
nginx started stefan.bauer /Users/stefan.bauer/Library/LaunchAgents/homebrew.mxcl.nginx.plist
mysql started stefan.bauer /Users/stefan.bauer/Library/LaunchAgents/homebrew.mxcl.mysql.plist
blackfire-agent started stefan.bauer /Users/stefan.bauer/Library/LaunchAgents/homebrew.mxcl.blackfire-agent.plist
supervisor started stefan.bauer /Users/stefan.bauer/Library/LaunchAgents/homebrew.mxcl.supervisor.plist
It's not necessary, to use these. I just wanted to mention it for the sake of completeness. For now, we only need PHP >= 7.0, a webserver (nginx or apache for instance) and MySQL as the database server. I also assume that you have the package manager composer
already installed and are used to use it. It should also be in your path, so you can use it from everywhere in your file system.
I create my new project in my home directory within a folder called Code
as Valet does it. So let's create that directory, if it doesn't exist and cd
into it from the terminal. And oh, I use of course iTerm2 for that. I prefer using the Laravel Installer. If you haven't it, just download the installer using composer.
$ composer global require "laravel/installer"
Make sure, the composer's vendor bin directory is in your $PATH
so the Laravel executable can be located. The cool thing about the installer is, that you can just use now laravel new
to create a fresh Laravel installation within the specified directory. So in our case:
$ laravel new pingping
Alternatively, you may also install Laravel using composer directly via
$ composer create-project --prefer-dist laravel/laravel pingping
At the time of writing this post, Laravel is at version 5.5.32
.
As I told you, I build this project in public. Therefore I created an empty repository on GitHub, where you can follow the entire development process, collaborate with pull requests or just use the issues to track to-dos, ideas or bugs. You can find the repository at https://github.com/stefanbauer/pingping.
If you want to code along with me, you can use your own repository. The first thing I always do after installing a new project, I create a brand new local repository, commit the naked current state and push it to the remote repository to have a clear reference point. Actually, I use always git-flow, as I am a big fan of it. But in this case, I'm gonna stick with a simple master branch for now. Let's cd
into our pingping
project directory.
$ git init
$ git add .
$ git commit
Now I enter as the commit message something like initial commit with naked Laravel 5.5.32
.
Oh and by the way. In the future, I'm gonna use my personal git aliases. If you're interested in, have a look at this post here. To make getting started easier, I show you these details only in this post. In upcoming posts, I will just refer to things like pushing, committing or rebasing.
Then let's push it up to the remote. First, we have to add the remote. Usually, this is called origin
.
$ git remote add origin git@github.com:stefanbauer/pingping.git
After I have done that, we have to use for the very first time of pushing it up
$ git push -u origin master
instead of a simple git push
. git push -u
is the equivalent to git push --set-upstream
. This is necessary to tell git, that you'd like to push to the remote and enable tracking for this branch. Finally you have to add the remote name, where the branch should be pushed to and of course the name of the branch, which should be pushed.
That's it. We are done with git. Congratulations!
By the way: You can of course clone this project directly, if you don't like to work along with me. But please don't forget to install all the composer and yarn/npm dependencies.
$ composer install yarn install
Open the new project by using your editor of choice und let's get started to do some basic setup.
For a couple of reasons, I use in every single project the PHP Coding Standards Fixer which is a great tool. It fixes the code to the given standards. But one step at a time.
Short excursion: As soon as several team members are working on a project, I think it makes sense to use something like this. This ensures the same coding standard and code always looks identical. At least structurally. From my many years of experience, I can confirm that such a tool is worth in any case.
I suggest you to install it globally via composer, like the Laravel Installer. So let's do it.
$ composer global require friendsofphp/php-cs-fixer
You still have to make sure, same as with the Laravel Installer, that your Composer's binaries directory is in your $PATH
. But I guess, it should be meanwhile though. Anyways. If we type php-cs-fixer
in the terminal, you should get information about the usage. If that happens, everything went well. If it doesn't work, there is a big chance, that you have to restart your terminal session if you added the Composer's binary directory now and you forgot to source your bashrc/zshrc, or whatever shell you're using.
If that works for you, it's time to create a little configuration file, that defines what our cs-fixer should take care about, which paths should be under control and what it needs to fix. Most people use as the main configuration rule the PSR-2
standard. For me personally, I'll go a little bit further and use the Symfony
standard. It's on top of the PSR-2
with some more restrictions and some more settings that I find useful. Additionally to that default configuration, it is possible to override each option, which is set by the default setting. One of these settings I always change is the ordered_imports
to the sortAlgorithm
to length
. What this does is, it orders the use statements by length and not by alphabet. But this comes down to your personal preference. It's up to you if you like that or not. All that code should go into a .php_cs.dist
in your root directory.
--- /dev/null
+++ b/.php_cs.dist
@@ -0,0 +1,23 @@
+<?php
+
+namespace PhpCsFixer;
+
+$finder = Finder::create()
+ ->name('*.php')
+ ->in(__DIR__.DIRECTORY_SEPARATOR.'app')
+ ->in(__DIR__.DIRECTORY_SEPARATOR.'tests')
+;
+
+return Config::create()
+ ->setUsingCache(false)
+ ->setRiskyAllowed(true)
+ ->setRules([
+ '@Symfony' => true,
+ 'strict_param' => true,
+ 'array_syntax' => ['syntax' => 'short'],
+ 'ordered_imports' => ['sortAlgorithm' => 'length'],
+ 'phpdoc_order' => true,
+ 'phpdoc_annotation_without_dot' => false,
+ ])
+ ->setFinder($finder)
+;
In my environment setup, the cs-fixer runs immediatelly, when I save a file. So it can never ever happen, that I commit something, that does not fit the coding standards. Later, we're gonna to use a tool like StyleCI. This tool reads our cs-fixer configuration and applies the changeset automatically via pull request. But one step at a time.
For me, I don't like the default .gitignore much for several reasons.
For now, let's use the following .gitignore
.
--- a/.gitignore
+++ b/.gitignore
@@ -1,12 +1,13 @@
+.env
+!composer.lock
+!phpunit.xml
/node_modules
-/public/hot
-/public/storage
+
+/public/*
+!/public/images
+!/public/index.php
+!/public/favicon.ico
+!/public/robots.txt
+
/storage/*.key
/vendor
-/.idea
-/.vagrant
-Homestead.json
-Homestead.yaml
-npm-debug.log
-yarn-error.log
-.env
You might ask yourself, why the hell I ignore /public/*
. The thing is, that we're using Laravel Mix and we really don't need anything in the public folder, but the index.php
, the favicon.ico
and the robots.txt
for now. Everything else, will be copied over during our deployment process using Laravel Mix. Even the images are not necessary in my opinion. But let's keep it there for now and see where we're getting.
A quick side note: I exclude composer.lock
and phpunit.xml
.
The reason for the composer.lock
is, that when developing libraries, it's not necessarily recommended to commit the lock file. So I have the this file in my global gitignore
. The reason for excluding the phpunit.xml
is, that in general I think something like this and it might be, that we change that later together:
For a predefined phpunit.xml
I would rename it to phpunit.xml.dist
, like the .env.example
(I would call it also .env.dist
by the way). With that, you got always distribution files. You can of course work with exactly these files on your machine. Don't worries. But if you would like to have a different local configuration than your team mates, you can create your personal phpunit.xml
and the phpunit.xml.dist
will remain untouched. With that in mind, it is possible that every single team mate could have it's own phpunit configuration without any hassle.
But you know what? Let's do it now.
Here is nothing much to say. I will rename the phpunit.xml
to phpunit.xml.dist
behind the scenes and we're good to go. We're gonna customize this file later, if we need to. But the cool thing is now, that if in this distribution file is used mysql for instance, you can create your own local version with in-memoery sqlite database, without taking care if you are safe to to push that phpunit.xml(.dist)
file or not.
So that everything is done right away, we also rename the .env.example
to .env.dist
. Cool!
What we forgot is, that we've to remove the app.js
and app.css
which are located in the public
folder, because these compiled assets are generated by npm.
$ git rm --cached public/css/app.css
$ git rm --cached public/js/app/js
--cached
in this case means that we remove the files from the index, but keep a copy in the working tree. This is exactly what we want, cause locally we need these files.
Now that we've changed some files and modified the .gitignore
, there are also some new files to track. Add it, commit it and push it.
$ git add .
$ git commit
$ git push
For today we're done. Actually, to be honest, my plan was to integrate TailwindCSS in this episode and start with the the first frontend topic - the Login. Just because I think there's nothing better than seeing immediate results.
Anyways, now I told you not only what I did and copied some code, I also told you why I did things like I did it and what my experience is in different situations. So if you have any questions about that, let me know on Twitter or shoot me a mail. In the next episode we will really start to integrate TailwindCSS and the Login. Keep on coding!