Skip to main content

2017: Getting started with Laravel 5.4 on Windows

It can be quite overwhelming to get started with Laravel on Windows OS. This was meant to guide you through a fresh install. Just imagine you bought a new Windows computer and you want to start web-development, specifically with Laravel. This guide is for you. With that said, lets begin:

Install WAMP
  • You need this for PHP, MySQL, Apache
  • Go to http://www.wampserver.com/en/
  • Click Download
  • Based on your computer's architecture, select either the 32-bit or 64-bit download option (mine is a 64-bit)
  • Click download directly.
  • If you get an error or sourceforge.net, look at the middle of the page and find:
    •  Looking for the latest version? Download wampserverxx.xx.xx_x64.exe (xxx.x MB)
  • Once you download it, run it and install it.
  • Open it and you'll see the WAMP server logo in the task bar. Hopefully it's green.
  • Left-click on the icon and scroll over PHP, then Version. Click on the latest version of PHP. Currently it's at 7.1.9.
  • At this point, just to make sure that everything takes effect, restart your computer.
  • Run WAMP again.
  • Open CMD and type php -v
    • Hopefully you'll see the version of PHP you selected.
  • Open your browser and type http://localhost
    • You should see the default page
Install Node.js and NPM
  • You'll need this when you start creating .scss files and .js files, the Laravel way.
  • You'll quickly realize that you need it, so lets get it.
  • Go to https://nodejs.org/en/
  • You'll see the download button on the main screen. Download either the stable version or current one. It's up to you.
  • Install it.
  • If you have CMD open, close it and open it again.
  • Type node -v
    • Hopefully you'll see the version.
  • Type npm -v
    • Hopefully you'll see the version.
Install Composer
  • You'll need this to be able to get Laravel
  • Go to https://getcomposer.org/
  • Click Download
  • Look where it says Download and run Composer-Setup.exe
  • Click on it and install it.
  • Open/Restart CMD and type composer
    • You should see a bunch of options that populate
Install Laravel
  • Open CMD
  • Type composer global require "laravel/installer"
  • Restart CMD
  • Type laravel
    • Hopefully it displays some options for you
  • Wait until it finishes and it would be a good time to restart your computer to make sure that everything is good to go.
Creating a new project
  • Open your wamp root directory
    • If you followed the above steps it'll be located in C:/wamp64/www
  • For testing, create a new folder called laravel (or whatever you choose to name it. You can store all of your Laravel projects here).
  • Open CMD and navigate to the folder that you just created
    • i.e. cd C:/wamp64/www/laravel
  • Next is time to use the laravel utility
  • Type in laravel new project-name
    • i.e. if you wanted to create a project name of homepage, you would type in laravel new homepage
  • You'll see all of the necessary files being downloaded
  • Once finished, navigate to your folder to verify that everything is in there
  • Also, in CMD, cd into the newly created project
    • i.e. cd homepage
  • You'll need to do some stuff with npm if you start creating .scss projects
  • Type npm install
    • It'll take some time, so be patient
  • Type php artisan
    • It should populate with options. If you don't see them, you may need to navigate to the root directory (i.e. the newly created project. In this example C:/wamp64/www/laravel/homepage)
That's it...but let's go ahead and run through some functionality that you'll need

Here are the steps that you would take to create a website with the main page, and a contact page. For demonstration, on the contact page, we'll have the ability to:
  • Submit a new message
  • View the message
  • View all messages
  • Delete a message
  • Edit a message
As you might expect, you'll probably need a way to store the contact information into a database. Lets go ahead and create a database first. 
  • Your WAMP installation comes with phpMyAdmin.
  • In your browser, navigate to http://localhost/phpMyAdmin
  • Your username is root
  • The password field is empty
  • If you have the option to select the server choice, select MySQL.
  • Click the Databases tab
  • Type in a Database Name and click Create.
    • For this example, I created a database titled homepage
  • Open up the C:/wamp64/www/laravel/homepage folder in the editor of your choice. For example SubLime or JetBrains PHPStorm.
  • In the root directory, open the .env file
  • Make sure the following setting look like this
      DB_CONNECTION=mysql
      DB_HOST=127.0.0.1
      DB_PORT=3306
      DB_DATABASE=homepage
      DB_USERNAME=root
      DB_PASSWORD=
    
    
  • We'll comeback to creating the contact page later on
  • Now, since your folder is in www/laravel/homepage and not in the www folder, we'll need to correct that too so that the links you generate will be properly created.
  • Open app/Providers/AppServiceProvider.php
  • Inside the boot() method, add the following line of code:
    
      public function boot()  {      
        app()->instance('path.public', 'localhost/laravel/homepage/public/');
      }
    
    
  • Now let's just test to make sure that everything works.
  • Go to http://localhost/experiment/laravel/homepage/public/
  • You should see the default Laravel page (hopefully no errors)
If everything looks good, it's time to proceed to creating your home page. All of the directions assume that you've opened up the root directory (in our case homepage)
  • You'll be using CMD so make sure to have it open and that you've navigated to the root directory (cd C:/wamp64/www/laravel/homepage)
  • We'll do this the strict MVC way. There'll be tutorials everywhere that tell you that sometimes you don't need a controller, but we'll always create one. In MVC, the Controller dictates the communication between the Model and the View. The Model does the heavy code lifting and normally communicates with the database. The View outputs information to the screen. So, your Controller will call the Model to get some data from the database and pass that data to the view. The View knows how to display that data.
  • In our case, we're not going to need to communicate with the database so there's really no need to create a model.
  • First, open up routes/web.php and type in the following
    
      Route::get('/', 'IndexController@index');
    
    
  • It states that when the user visit the main page, load the index method in the IndexController
  • In CMD, making sure that you're in your root directory, type in php artisan make:controller IndexController
  • In your editor, navigate to app/Http/Controllers. You'll see your IndexController
  • Open it
  • Create a new function
      
      public function index() {
          $data['title']         = 'Dino Cajic';
    
          $data['description']   = 'Dino is pretty cool.';
          return view('index.index', compact('data'));
    }
  • You'll be returning a view. That view, named index, will be located inside the index folder.
  • Lets go ahead and create the index view
  • In resources/views create a new directory and name it index
  • Create a new file within the newly created index directory and name it index.blade.php
  • Laravel uses a template engine named blade so that's why there's the .blade.php after index
  • Copy some basic HTML data into it and test it by reloading your http://localhost/laravel/homepage/public/
  • If we look at most page, you'll see that they follow a similar structure
    • Navigation bar
    • Middle content
    • Footer
  • We just need to change the middle content so lets go ahead and create a layout.
  • Navigate to resources/views and create a page titled layout.blade.php
  • It should contain something like the following
    
      <!DOCTYPE html>  
      <html lang="en">  
      <head>
          <title>{{ $title }}</title>
          <meta charset="utf-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <meta name="description" content="{{ $description }}" />
          <meta name="author" content="Your Name here" />
            <link rel="shortcut icon" href="{!! url('/images/favicon.ico') !!}">
    
          <!-- The Stylesheet -->
          <link rel="stylesheet" href="{!! url('/css/app.css') !!}">
          @yield ('additional_header')
      </head>
      <body>
          @include('partials.nav')
          @yield('content')
          @include('partials.footer')
    
          @yield('additional_scripts')
      </body>
      </html>
    
    
  • All kinds of stuff happening here. If you remember, in the IndexController we created the $title and $description variables. We haven't passed them here yet, but we'll get there shortly. 
  • As you can see, they're surrounded with {{ }}. Laravel's blade translates this to <?php echo $title; ?>
  • To display a url, use {!! url('/path/to/wherever') !!}
  • Your css, images and js files will be located in the public directory. If you open up the public/css folder you'll see that app.css already exists.
  • If you want to create your own CSS, you can store it in the app.css or create a new file (for example stylesheets.css)
  • If you wanted to use SASS to create CSS files, navigate to the resources/assets folder. You'll place your JavaScript, SASS and Less code here.
  • For now, open up sass/app.scss
  • Delete the data from there and add your own SASS code here
  • Once you save it, open CMD and type in npm run dev
    • This will create the public/css/app.css file 
    • If you navigate to the public directory and open the app.css folder you'll see your newly created css code
  • If you wanted to create a new css file, create a new scss file in the resources/assets/sass folder. Name it, for example, contact.scss
  • Add some scss code. Since Laravel doesn't know that contact.scss exists, we'll need to add it.
  • In your root directory, open webpack.mix.js
  • You'll have to edit some code. It'll look similar to this when your done.
    
      mix.js('resources/assets/js/app.js', 'public/js')
         .sass('resources/assets/sass/app.scss', 'public/css')
          .options({
              processCssUrls: false
          })
          .sass('resources/assets/sass/contact.scss', 'public/css')
          .options({
              processCssUrls: false
          });
    
    
  • As you can see, the app.scss file has been added and the contact.scss file. 
  • A processCssUrls option has been set to false.
    • If you wanted to add a background image, and it's located in public/images/ but your css file is located in public/css, your image location needs to be something like the following
      
        background: url("../images/cover.jpg") no-repeat top center;
      
      
    • Unfortunately when you run npm, it'll throw an error.
    • If you set the processCssUrls option to false, you'll be able to type in npm run dev into CMD and run it without errors.
    • You'll notice a new contact.css file has been created in the public/css/ folder
  • Now we'll continue looking at the layout.blade.css file.
  • You'll quickly notice two tags: @yield and @include
    • The way I like to think of it is, @yield is optional and @include is required
  • The first @yield is @yield ('additional_header'). For certain pages you may want to include some additional css that's only specific to that page. That would be a perfect place to add it.
  • In my resources/views directory I created a new folder named partials. Within partials I've added some code that I would like to separate but will be reused on all page. The first one is the navigation bar and the second is the footer. It just makes for easier editing. The two files within  the partials directory are named nav.blade.php and footer.blade.php and are referenced with @include('partials.nav') and @include('partials.footer').
  • In the middle of those two includes is another @yield statement: @yield('content'). This is what's going to be different on each page. So we'll create the unique content for each page.
  • Last is @yield('additional_scripts'). If you need to include some additional JavaScript for a specific page, this would be the perfect place to put it.
Let's recap. We created a route to point to the IndexController's index() method. The index method creates a title and description and calls the index view located in the index controller. Let's create the index controller. This will be the @yield('content').
  • Create the file resources/views/index/index.blade.php and add the following code
    
      @extends('layout', 
               ['title' => $data['title'], 'description' => $data['description']])
    
      @section('content')
        <!-- Main image and info -->
        <div id="main-background">
          <img src="{!! url('/images/dino-cajic.png') !!}" alt="Dino Cajic" />
          <h1>Dino Cajic</h1>
          <h2>Computer Science Student</h2>
        </div>
    @endsection
  • The first thing would be to include the layout.blade.php file. You'll do that with @extends. 
  • The second parameter of @extends is the data that you want to pass to it. As you can see, the $data array gets passed from the IndexController into the index.blade.php view and once the layout.blade.php view is extended, the $data is passed there.
  • In the layout.blade.php file, we specified that @yield('content') which means, place the code that's surrounded with the @section('content') tag here.
There we go. You just created a web-page. To create additional pages, just follow the steps above. Make sure that you:
  • Create a route in web.php, i.e. Route::get('/contact', 'ContactController@index');
  • php artisian make:controller IndexController
  • Modify the IndexController
  • Create the view
  • Return the view inside the controller
Let's create a page that requires access to the database. For this example, we'll create a contact form.
  • You'll want to navigate to the database/migrations folder. There will be two files there already, a users and password migration files. We may have to delete these if we get some errors later on.
  • Lets create the contact table
  • In CMD, type in php artisan make:model Contact -mc
    • What does this statement mean? Create a new model named Contact. Also, create a migration file that'll be used to create the contact table and create a Contact Controller.
    • If it fails, you might have to execute the following command: composer dump-autoload
    • If you open the database/migrations/xxxcreate_contact_table.php file, you can specify the structure of the contacts table. By convention, your tables are going to be plural and your models will be a singular form of the table. 
    • Add the following code to the up() method
      
        public function up()
        {
            Schema::create('contacts', function (Blueprint $table) {
                $table->increments('id');
                $table->string('first_name');
                $table->string('last_name');
                $table->string('email');
                $table->string('phone');
                $table->text('message');
                $table->boolean('read')->default(false);
                $table->timestamps();
            });
        }
      
      
  • It'll create a contact table with a VARCHAR(255) first_name, etc, columns.
  • To create the table, in CMD, type in php artisan migrate. 
    • You can see the contact table in phpMyAdmin
  • Quick side-note, if we follow restful conventions, for each table you'll need the following
    • View all of the posts
      • GET /posts
    • Create a post: i.e. display a form
      • GET /posts/create
    • When you submit a post, store in database
      • POST /posts
    • Edit an existing post. Display form to edit post
      • GET /posts/{id}/edit
    • When you submit the edit form
      • PATCH /posts/{id}
    • Displays a single post
      • GET /posts/{id}
    • If you click a button delete post, this will instruct the server to delete a post
      • DELETE /posts/{id}
        • To use the delete Route, you'll need to submit it via a form. If you want to delete an entry from the database coming from a link, you'll use Route::get() 
  • Alright, so for our Contact table, we'll need to be able to:
    • Send a message
      • Display empty form
      • Submit the message
    • View all messages
    • View a single message
    • Edit a message
      • Display pre-populated form
      • Update data in contacts table for that specific id
    • Delete a message
  • Let's modify the resource/web.php file first
    
      /* Main Page */
      Route::get('/', 'IndexController@index');
    
      /* Contact Form Routes */
      Route::get('/contact/create',        'ContactController@create');
      Route::post('/contact',              'ContactController@store');
      Route::get('/contact',               'ContactController@index');
      Route::get('/contact/{id}',          'ContactController@show');
      Route::get('/contact/{id}/edit',     'ContactController@edit');
      Route::patch('/contact/update/{id}', 'ContactController@update');
      Route::get('/contact/destroy/{id}',  'ContactController@destroy');
    
    
  • Next, we'll need to modify the app/Http/Controllers/ContactController.php file.
    
      <?php
      namespace App\Http\Controllers;
    
      use Illuminate\Http\Request;
      use App\Contact;
    
      class ContactController extends Controller
       {
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function index()
        {
            $data['title']       = "All Contact Messages";
            $data['description'] = "Display all of the contact messages";
    
            $contact = new Contact();
            $data['messages']    = $contact->latest()->get();
    
            return view('contact.index', compact('data'));
        }
    
        /**
         * Show the form for creating a new resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function create()
        {
            $data['title']       = 'Contact';
            $data['description'] = 'Contact Dino Cajic';
    
            return view('contact.create', compact('data'));
        }
    
        /**
         * Store a newly created resource in storage.
         *
         * @param  \Illuminate\Http\Request $request
         * @return \Illuminate\Http\Response
         */
        public function store(Request $request)
        {
            $rules = array(
                'first_name' => 'required',
                'last_name'  => 'required',
                'email'      => 'required|email',
                'phone'      => 'required',
                'message'    => 'required'
            );
    
            $request->validate($rules);
    
            // Insert contact info into database if validation passed
            $contact = new Contact();
            $contact->first_name = $request->post('first_name');
            $contact->last_name  = $request->post('last_name');
            $contact->email      = $request->post('email');
            $contact->phone      = $request->post('phone');
            $contact->message    = $request->post('message');
            $contact->save();
    
            return redirect()->back()->with('success', 
                                   'Your message has been successfully submitted.');
        }
    
        /**
         * Display the specified resource.
         *
         * @param int $id
         * @return \Illuminate\Http\Response
         */
        public function show($id)
        {
            $data['title']       = "Individual Post";
            $data['description'] = "Each individual description is listed here";
    
            $contact             = new Contact();
            $data['message']     = $contact->find($id);
    
            return view('contact.show', compact('data'));
        }
    
        /**
         * Show the form for editing the specified resource.
         *
         * @param int $id
         * @return \Illuminate\Http\Response
         */
        public function edit($id)
        {
            $data['title']       = "Edit Message";
            $data['description'] = "Edit each individual contact message";
    
            $contact             = new Contact();
            $data['message']     = $contact->find($id);
    
            return view('contact.edit', compact('data'));
        }
    
        /**
         * Update the specified resource in storage.
         *
         * @param \Illuminate\Http\Request $request
         * @param int $id
         * @return \Illuminate\Http\Response
         */
        public function update(Request $request, $id)
        {
            $rules = array(
                'first_name' => 'required',
                'last_name'  => 'required',
                'email'      => 'required|email',
                'phone'      => 'required',
                'message'    => 'required'
            );
    
            $request->validate($rules);
    
            // Update contact info if validation passed
            $contact = Contact::find($id);
            $contact->first_name = $request->post('first_name');
            $contact->last_name  = $request->post('last_name');
            $contact->email      = $request->post('email');
            $contact->phone      = $request->post('phone');
            $contact->message    = $request->post('message');
            $contact->save();
    
            return redirect()->back()->with('success',
                                  'Your message has been successfully edited.');
        }
    
        /**
         * Remove the specified resource from storage.
         *
         * @param int $id
         * @return \Illuminate\Http\Response
         */
        public function destroy($id)
        {
            Contact::destroy($id);
    
            return redirect('/contact');
        }
      }
    
    
  • The Contact model extends the Model class. Most of the work is already done for us. 
  • In the index() method, we want to retrieve all of the items. 
    • We do that with: $contact->latest()->get(); The latest() method is not necessary but helps retrieve it by the latest entry. Your view should be able to output the data. 
  • The destroy() method deletes the entry from the database by calling the destroy() method
  • The create() method displays the new message form.
    
      @extends('partials.layout', 
               ['title' => $data['title'], 
                'description' => $data['description']])
    
      @section('additional_header')
        <link rel="stylesheet" href="{!! url('/css/contact.css') !!}">
      @endsection
    
      @section('content')
        <div class="contact">
            <h1>Contact Page</h1>
    
            <div class="container">
                @if (\Session::has('success'))
    
                    <div class="alert alert-success">
                        <h2>{!! \Session::get('success') !!}</h2>
                    </div>
                @endif
    
                @if ($errors->any())
    
                    <div class="alert alert-danger">
                        <ul>
                            @foreach ($errors->all() as $error)
    
                                <li>{{ $error }}</li>
                            @endforeach
    
                        </ul>
                    </div>
                @endif
    
                <form method="POST" action="{!! url('/contact') !!}">
                    {{ csrf_field() }}
    
                    <label for="fname">First Name</label>
                    <input type="text" 
                           id="fname" 
                           name="first_name" 
                           value="{{ old('first_name') }}" 
                           placeholder="Your name.." 
                           required>
                    <label for="lname">Last Name</label>
                    <input type="text" 
                           id="lname" 
                           name="last_name" 
                           value="{{ old('last_name') }}" 
                           placeholder="Your last name.." 
                           required>
                    <label for="email">Email</label>
                    <input type="text" 
                           id="email" 
                           name="email" 
                           value="{{ old('email') }}" 
                           placeholder="Your email address.." 
                           required>
                    <label for="phone">Phone</label>
                    <input type="text" 
                           id="phone" 
                           name="phone" 
                           value="{{ old('phone') }}" 
                           placeholder="Your phone number.." 
                           required>
                    <label for="subject">Subject</label>
                    <textarea id="subject" 
                              name="message" 
                              placeholder="Write something.." 
                              required>{{ old('message') }}</textarea>
                    <input type="submit" value="Submit">
                </form>
            </div>
        </div>
      @endsection
    
    
    • When creating your form, make sure that you add {{ csrf_field() }}. This is for site protection.
  • Once the user clicks on submit, the store() method will store the data into the contacts table
    • If any validation errors occur, the errors will be returned and the data will not be stored
  • The show() method will display the individual message.
  • The edit() method will display the pre-populated form and allow the user to edit the message
  • Once the user clicks on Update, the update() method will take care of the rest.
  • The code is simple and should not require any extra explanation beyond what I listed here.
I hope that helps. All of the code can be seen on my GitHub page: https://github.com/dinocajic/laravel-home-page

Comments

  1. Excellent blog on Web technology!!! Have gained more information related to website development. Thank admin for this wonderful content.
    website design classes
    web designing classes in chennai

    ReplyDelete
  2. Thank administrator for this awesome content.Please keep composing on this blog.
    Latest Updates

    ReplyDelete
  3. The gave data's are exceptionally valuable to me. It's a magnificent site for learning web application. Much obliged to you for sharing this awesome blog.
    MBA Talks | Article Submission sites | Education | Technology

    ReplyDelete
  4. This is an awesome post.Really very informative and creative content.
    Guest posting sites
    Article submission sites

    ReplyDelete
  5. Hi, Excellent Content, your blog is very useful and also interesting to read. Keep sharing this type of information.

    PHP Training Center in Chennai
    PHP Course Chennai

    ReplyDelete
  6. I feel happy to find your post, excellent way of writing and also I would like to share with my colleagues so that they also get the opportunity to read such an informative blog.
    java training institute in chennai
    java classes in chennai

    ReplyDelete
  7. Hey Nice Blog!! Thanks For Sharing!!!Wonderful blog & good post.Its really helpful for me, waiting for a more new post. Keep Blogging!
    digital marketing course in coimbatore
    php training in coimbatore

    ReplyDelete
  8. Thank you for writing this informative post. Looking forward to read more.
    Laravel Web Development Services

    ReplyDelete
  9. HireFullStackDeveloperIndia is one of the best Mobile App Development Company in Jeddah that develop a client's dream app idea into a powerful mobile application. They create mobile apps for a variety of handheld devices that are responsive enough to adapt to changing market trends. They are well versed in developing mobile apps for Android, iOS, iPad, and Windows that satisfy your app requirements with value for money and prompt service.

    ReplyDelete

Post a Comment

Popular posts from this blog

Beginner Java Exercise: Sentinel Values and Do-While Loops

In my previous post on while loops, we used a loop-continuation-condition to test the arguments. In this example, we'll loop at a sentinel-controlled loop. The sentinel value is a special input value that tests the condition within the while loop. To jump right to it, we'll test if an int variable is not equal to 0. The data != 0 within the while (data != 0) { ... } is the sentinel-controlled-condition. In the following example, we'll keep adding an integer to itself until the user enters 0. Once the user enters 0, the loop will break and the user will be displayed with the sum of all of the integers that he/she has entered. As you can see from the code above, the code is somewhat redundant. It asks the user to enter an integer twice: Once before the loop begins, and an x amount of times within the loop (until the user enters 0). A better approach would be through a do-while loop. In a do-while loop, you "do" something "while" the condition

Programming Language Concepts Questions/Answers Part 3

1. What is an associative array? - An unordered collection of data elements that are indexed by keys. 2. Each element of an associative array is a pair consisting of a _______ and a _______. - key and a value 3. True or False? Java supports associative arrays? - True. As a matter of fact, Perl, Python, Ruby, C++, C# and F# do too. 4. What are associative arrays called in Perl? - hashes 5. Why are associative arrays in Perl called hashes? - Because their elements are stored and retrieved with a hash function 6. What character does a hash in Perl begin with? % 7. In Perl, each key is a _____ and each value is a _______. - string - scalar 8. In Perl, subscripting is done using _______ and _______. - braces and keys 9. In Perl, how are elements removed from hashes? - using delete 10. In Perl, the ________ operator tests whether a particular value is a key in a hash. - exists 11. What are associative arrays called in Python? - dictionaries 12. What is a dif

Creating your own ArrayList in Java

Wanted to show that certain data structures in Java can be created by you. In this example, we'll go ahead and create an ArrayList data structure that has some of the methods that the built in ArrayList class has. We'll create 2 constructors: The default constructor that creates an ArrayList with a default size of 10. Constructor that allows an initial size to be passed to the array. We'll also create a number of methods: void add(Object x);  A method that allows you to place an Object at the end of the ArrayList. void add(int index, Object x);  A method that allows you to place a value at a given location. Object get(int index):  Allows you to retrieve a value of the arrayList array from a given location. int size();  Allows you to get the number of elements currently in the Arraylist. boolean isEmpty();  Tests to see if the Arraylist is empty. boolean isIn(Object x);  A method that sees if a particular object exist in the arrayList. int find(Object x);