Tuesday, 28 June 2016

Laravel the easy install on Win 10

(Or the joy of Vagrant on VMware)


So your running a Win 10 rig, but you want all the lovely goodness of Laravel. You can, as I have, munch your way through the numerous setup pages on the internet, including Laravel's own install instructions.

You've fought WAMP and XAMPP and if you insist on running linux designed software on windows then please carry on the good fight. If you just want a setup that is quick and painless then please carry on reading.

Doing it the easy way.

The easy way is to use git and vagrant, specifically git bash, and because its vagrant it will want virtualbox (or other vm).

For this Recipe you will need the following ingredients:-


1) a windows 10 computer with some welly (enough to run the vm's).

2) git - specifically MINGW64 - get it hot from the bakery door at https://git-scm.com/download/win you will need git version 2.7.0.windows.1.

3) vagrant - https://www.vagrantup.com/downloads.html - you will need 1.8.5v of this.

4) virtualbox - https://www.virtualbox.org/wiki/Downloads - but this page is abit crappy as it has lost of builds. Alternativly vagrant will install virtual box for you, otherwise you probably need VirtualBox 5.0.24 for Windows hosts (the version numbers may change).

4) Laravel homestead vagrant box - vagrant box add laravel/homestead.

Method:-


Install git and vagrant on your win 10 machine.

Open a git bash command line editor (this will most likely be alink on your desktop) or search for bash.

Using the command cd change the command line to the folder you want to work in (say your vagrant/projects/homestead folder for example, note: you may need to make this folder first, you can't cd into a folder which does not exist. You can use mkdir folderName or use the window explorer view).



Now create a provisions folder inside your project folder (You can call these folders anything you like, but you will need to edit the provisioning files, you should check them anyway).

Now you need a vagrantfile. I have created a simple vagrantfile.
Create a file called vagrantfile in your homestead directory and paste the following code into it.

# -*- mode: ruby -*-
# vi: set ft=ruby :


Vagrant.configure("2") do |config|

  config.vm.box = "laravel/homestead"

  config.vm.network "forwarded_port", guest: 80, host: 8080

  config.vm.provider "virtualbox" do |vbox|
    vbox.name = "homestead"
  end

  config.vm.provision "shell", inline: <<-SHELL
   echo "Updating"
   apt-get update
   echo "linking"
   ln -s /vagrant/provisions/nginx-default /etc/nginx/sites-enabled/default
   ln -s /vagrant/provisions/index.html /var/www/html/index.html
   echo "Resarting nginx"
   service nginx restart
  SHELL
end


You can now test that vagrant is working. on the bash command line, in your homestead folder, run vagrant up.



If all has gone well you should see vagrant provision itself. It should automatically down load the laravel homestead box. If it doesn't either your vagrant has not installed correctly, or you need to manually download the box, you can also try vagrant init laravel/homestead.

Once your vagrant is up test it with vagrant ssh. This should give you the command line on the client box (your new computer inside your computer).

Type sudo su - (To get root permissions)
Type exit exit (to exit out of root, then out of the client shell)

Your back in win gitbash.

Type vagrant destroy to destroy your vm box.

Now you need a nginx config file as homestead runs laravel on nginx webserver (not apache2).

index index.php index.html index.htm;

server {
  listen 80;
  server_name homestead;
  root /vagrant;
  try_files $uri $uri/ /index.php$is_args$args;

  location / {

  }

  location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    # \Add following to use sqlite as db.
    fastcgi_param DB_CONNECTION  sqlite;

    #fastcgi_index index.php; "fastcgi_index" directive is duplicate in /etc/nginx/sites-enabled/default:18
  }

  location ~ /\.ht {
      deny all;
  }

}



Create a file called nginx-default in the provisions folder, you will see this is referenced in the vagrantfile line 19 ln -s /vagrant/provisions/nginx-default /etc/nginx/sites-enabled/default.
This tells vagrant, once the client server is running execute a line of bash script on the client command line, thus, the uri's are referenced as if from the client, not the host machine.

Assuming all goes well try http://localhost:8080 and you should get either a 404 (at least the nginx server responded) or the  index.html page you put into your provisions folder.

Now all you have to do vagrant ssh to the client command line.

Type vagrant ssh

Type sudo su - (To get root permissions)

Type composer global require "laravel/installer"

This will load laravel installer to your client machine.

Type cd /vagrant (This will put the command line in the /vagrant folder on the client, which is also your folder on your host).

Type  ~/.composer/vendor/bin/laravel new laravel.site

Call your site what you like (new mysite).

Composer will download a version of laravel 5 for you. You should see the new file stack on your host/win machine in you homestead folder (or wherever you ran the vagrant up command from).

Now try localhost:8080/mysite/public/ and Hey Presto you should have a page with Laravel 5 writen on it, telling you you have succeeded.

Note:- Check the two files for the uir's used, particularly if you used different folder names.
Note:- The trick here is rather than running composer and such on your windows box, you are running it in the client which is a laravel/homestead ubuntu build already configured with the necessary software.

Hope it works for you.

PHP sqlite3 class example

For some reason I like to run php on the command line in Win 10. To do this I use git bash (MINGW64) as my command line interface, you can also use cmd and powershell, but I like git.

I often use file_put_contents to write files for config users etc especially early on in the design of a project as this allows me to scaffold a project (ie: you need some users to build and test the users functions).

Having learn't of sqlite I wanted to get it to work on my rig and setup.

After some experimentation and research I build the following script which does the job on php 7.x running on win 10, using git bash cl.

Of course this only an example script which acts as notes to build something more practical, but it contains everything to get a simple db, table and some data in and out.




/** * Test script for implementing sqlite3. * I run this file on win 10 git bash command line using php v7.0. */ // I just like to know the script fired. print "running.\n"; // ----- Main program // Instansiate the sqlite3 class. $db = new myDb(); // Create a new database or open an existing one. openDb('test'); // Call exec method passing it create table sql. $db->execDb($db->createTableSql()); // Call either exec or query methods on an insert sql. // Note: either comment this out or change the name in getInsertSql() method // otherwise you will get Unique constraint (set on name in users) error. //$db->execDb($db->getInsertSql()); $db->queryDb($db->getInsertSql()); // Call query to retrieve all the data in the table. $result = $db->queryDb($db->getSelectSql()) or die('select failed.'); // pump out the results of the select query. while ($row = $result->fetchArray(SQLITE3_ASSOC)) { print_r($row); } // ----- End main /** * Running php on git bash cmmand using the class extends is the only way I have * found to get it to work. * The folowing class demonstraites the basic implementation of this technique. */ class myDb extends sqlite3 { // Not used in this example, but you might need it for something. public $dbHandle; function __construct () { } /** * Creates or opens the db file. * @param string $dbName This is the path and file name. */ function openDb ($dbName) { $this->dbHandle = $this->open($dbName); } /** * Calls the sqlite exec method on any sql sent to it. * @param string $sql * @return boolean true = success */ function execDb ($sql) { // exec does not return result sets. return $this->exec($sql); } /** * Calls the query method on any sql sent. Returns a result set if there is one. * @param string $sql * @return resultSet */ function queryDb ($sql) { // query returns result sets. return $this->query($sql); } // ----- The sql statements used in this example. function createTableSql () { return "CREATE TABLE IF NOT EXISTS users ( username STRING PRIMARY KEY, password STRING); "; } function getInsertSql () { return "INSERT INTO users VALUES ( 'brian', 'secret' );"; } function getSelectSql () { return "SELECT * FROM users;"; } }