Laravel5.1入门

Published on 2017 - 03 - 12

Laravel is a web application framework that borrows from the very best features of other popular framework solutions, among them Ruby on Rails and ASP.NET MVC. For this reason, if you have any experience working with other frameworks then I’d imagine you’ll make a pretty graceful transition to Laravel-driven development. If this is your first acquaintance with framework-driven development, you’re in for quite a treat! Frameworks are so popular precisely because they dramatically decrease the amount of work you’d otherwise have to do by making many of the mundane decisions for you, a concept known as convention over configuration.“Installing Laravel

Laravel Project Skeleton

With Laravel installed and configured, it’s time to get our hands dirty! We’re going to start by creating the TODOParrot application. There are a couple of different ways in which you can do this, but one of the easiest involves installing the Laravel installer using Composer:

$ composer global require "laravel/installer=~1.1"

After installation you’ll be able to create new Laravel project skeletons using the laravel utility’s new command:

$ laravel new dev.todoparrot.com
Crafting application...
Application ready! Build something amazing.

This command creates a new Laravel skeleton project in the directory dev.todoparrot.com. These contents are a combination of files and directories, each of which plays an important role in the functionality of your application so it’s important for you to understand their purpose. Let’s quickly review the role of each:

  • .env: Laravel 5 uses the PHP dotenv to conveniently manage environment-specific settings. You’ll use .env file as the basis for configuring these settings. A file named .env.example is also included in the project root directory. This file should be used as the setting template, which fellow developers will subsequently copy over to .env and change to suit their own needs. I’ll talk about this file and Laravel 5’s solution for managing environment settings in the later section, “Configuring Your Laravel Application”.
  • .gitattributes: This file is used by Git to ensure consistent settings across machines, which is particularly useful when multiple developers using a variety of operating systems are working on the same project. The lone setting found in your project’s .gitattributes file (text=auto) ensures file line endings are normalized to LF whenever the files are checked into the repository. Plenty of other attributes are however available; Scott Chacon’s book, “Pro Git” includes a section (“Customizing Git - Git Attributes”) with further coverage on this topic.
  • .gitignore: This file tells Git what files and folders should not be included in the repository. You’ll see the usual suspects in here, including the annoying OS X .DS_Store file, Windows’ equally annoying Thumbs.db file, and the vendor directory, which includes the Laravel source code and various other third-party packages.
  • app: This directory contains much of the custom code used to power your application, including the models, controllers, and middleware. We’ll spend quite a bit of time inside this directory as the application development progresses.
  • artisan: artisan is a command-line interface we’ll use to rapidly develop new parts of your applications such as controllers, manage your database’s evolution through a great feature known as migrations, and clear the application cache. You’ll also regularly use artisan to interactively debug your application, and even easily view your application within the browser using the native PHP development server. We’ll return to artisan repeatedly throughout the book as it is such an integral part of Laravel development.
  • bootstrap: This directory contains the various files used to initialize a Laravel application, loading the configuration files, various application models and other classes, and define the locations of key directories such as app and public. Normally you won’t have to modify any of the files found in the bootstrap directory, although I encourage you to have a look as each is heavily commented.
  • composer.json: Composer is the name of PHP’s popular package manager, used by thousands of developers around the globe to quickly integrate popular third-party solutions such as Swift Mailer and Doctrine into a PHP application. Laravel supports Composer, and you’ll use the composer.json file to identify the packages you’ll like to integrate into your Laravel application. If you’re not familiar with Composer you’ll quickly come to wonder how you ever lived without it. In fact in this introductory chapter alone we’ll use it several times to install several useful packages.
  • composer.lock: This file contains information about the state of the installed Composer packages at the time these packages were last installed and/or updated. Like the bootstrap directory, you will rarely if ever directly interact with this file.
  • config: This directory contains more than a dozen files used to configure various aspects of your Laravel application, such as the database credentials, and the cache, e-mail delivery and session settings.
  • database: This directory contains the directories used to house your project’s database migrations and seed data.
  • gulpfile.js: Laravel 5 introduces a new feature called Laravel Elixir. Gulpfile.js is used by Elixir to define various Gulp.js tasks used by Elixir to automate various build-related processes associated with your project’s CSS, JavaScript, tests, and other assets.
  • package.json: This file is used by the aforementioned Elixir to install Elixir and its various dependencies.
  • phpspec.yml: This file is used to configure the behavior driven development tool phpspec.
  • phpunit.xml: Even relatively trivial web applications should be accompanied by an automated test suite. Laravel leaves little room for excuse to shirk this best practice by configuring your application to use the popular PHPUnit test framework. The phpunit.xml is PHPUnit’s application configuration file, defining characteristics such as the location of the application tests. We’ll return to this topic repeatedly throughout the book, so stay tuned.
  • public: The public directory serves as your application’s root directory, housing the .htaccess, robots.txt, and favicon.ico files, in addition to a file named index.php that is the first file to execute when a user accesses your application. This file is known as the front controller, and it is responsible for loading and executing the application.
  • readme.md: The readme.md file contains some boilerplate information about Laravel of the sort that you’ll typically find in an open source project. Feel free to replace this text with information about your specific project. See the TODOParrot README file for an example.
  • resources: The resources directory contains your project’s views and localized language files. You’ll also store your project’s raw assets (CoffeeScript, SCSS, etc.).
  • storage: The storage directory contains your project’s cache, session, and log data.
  • tests: The tests directory contains your project’s PHPUnit tests.
  • vendor: The vendor directory is where the Laravel framework code itself is stored, in addition to any other third-party code. You won’t typically directly interact with anything found in this directory, instead doing so through the artisan utility and Composer interface.

Once the server is running, open your browser and navigate to the URL http://localhost:8000. Load this URL to your browser and you’ll see the page presented in the below figure.

As you can see, the Laravel logo is presented in the default page. So where is this page and logo located? It’s found in a view.

Setting the Application Namespace

Laravel 5 uses the PSR-4 autoloading standard, meaning your project controllers, models, and other key resources are namespaced. The default namespace is set to app, which is pretty generic. You’ll likely want to update your project’s namespace to something reasonably unique, such as todoparrot. You can do so using the artisan CLI’s app:name command:

$ php artisan app:name todoparrot
Application namespace set!

This command will not only update the default namespace setting (by modifying composer.json’s autoload/psr-4 setting), but will additionally updating any namespace declarations found in your controllers, models, and other relevant files.

Configuring Your Laravel Application

Most web frameworks, Laravel included, offer environment-specific configuration, meaning you can define certain behaviors applicable only when you are developing the application, and other behaviors when the application is running in production. For instance you’ll certainly want to output errors to the browser during development but ensure errors are only output to the log in production.

Your application’s default configuration settings are found in the config directory, and are managed in a series of files including:

  • app.php: The app.php file contains settings that have application-wide impact, including whether debug mode is enabled (more on this in a moment), the application URL, timezone, locale, and autoloaded service providers.
  • auth.php: The auth.php file contains settings specific to user authentication, including what model manages your application users, the database table containing the user information, and how password reminders are managed.
  • broadcasting.php: The broadcasting.php is used to configure Laravel 5.1’s new event broadcasting feature.
  • cache.php: Laravel supports several caching drivers, including filesystem, database, memcached, redis, and others. You’ll use the cache.php configuration file to manage various settings specific to these drivers.
  • compile.php: Laravel can improve application performance by generating a series of files that allow for faster package autoloading. The compile.php configuration file allows you to define additional class files that should be included in the optimization step.
  • database.php: The database.php configuration file defines a variety of database settings, including which of the supported databases the project will use, and the database authorization credentials.
  • filesystems.php: The filesystems.php configuration file defines the file system your project will use to manage assets such as file uploads. Currently the local disk, Amazon S3, and Rackspace are supported.
  • mail.php: it’s pretty easy to send an e-mail from your Laravel application. The mail.php configuration file defines various settings used to send those e-mails, including the desired driver (SMTP, Sendmail, PHP’s mail() function, Mailgun, and the Mandrill API are supported). You can also direct mails to the log file, a technique that is useful for development purposes.
  • queue.php: Queues can improve application performance by allowing Laravel to offload time- and resource-intensive tasks to a queueing solution such as Beanstalk or Amazon Simple Queue Service. The queue.php configuration file defines the desired queue driver and other relevant settings.
  • services.php: If your application uses a third-party service such as Stripe for payment processing or Mandrill for e-mail delivery you’ll use the services.php configuration file to define any third-party service-specific settings.
  • session.php: It’s entirely likely your application will use sessions to aid in the management of user preferences and other customized content. Laravel supports a number of different session drivers used to facilitate the management of session data, including the file system, cookies, a database, the Alternative PHP Cache, Memcached, and Redis. You’ll use the session.php configuration file to identify the desired driver, and manage other aspects of Laravel’s session management capabilities.
  • view.php: The view.php configuration file defines the default location of your project’s view files and the renderer used for pagination.

I suggest spending a few minutes nosing around these files to get a better idea of what configuration options are available to you. There’s no need to make any changes at this point, but it’s always nice to know what’s possible.

Configuring Your Environment

Laravel presumes your application is running in a production environment, meaning the options found in the various config files are optimized for production use. Logically you’ll want to override at least a few of these options when the application is running in your development (which Laravel refers to as local) environment. Laravel 5 completely overhauls the approach used to detect the environment and override environment-specific settings. It now relies upon the popular PHP dotenv package. You’ll set the environment simply by updating the .env file found in your project’s root directory to reflect the desired environment settings. The default .env file looks like this:

APP_ENV=local
APP_DEBUG=true
APP_KEY=SomeRandomString

DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

Laravel will look to this file to determine which environment is being used (as defined by the APP_ENV variable). These variables can then be used within the configuration files via the env function, as demonstrated within the config/database.php file, which retrieves the DB_DATABASE, DB_USERNAME, and DB_PASSWORD variables:

'mysql' => [
        'driver'    => 'mysql',
        'host'      => env('DB_HOST', 'localhost'),
        'database'  => env('DB_DATABASE', 'forge'),
        'username'  => env('DB_USERNAME', 'forge'),
        'password'  => env('DB_PASSWORD', ''),
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
        'strict'    => false,
],

Useful Development and Debugging Tools

There are several native Laravel features and third-party tools that can dramatically boost productivity by reducing the amount of time and effort spent identifying and resolving bugs. In this section I’ll introduce you to my favorite such solutions, and additionally show you how to install and configure the third-party tools.

The dd() Function

Ensuring the debug option is enabled is the easiest way to proactively view information about any application errors however it isn’t a panacea for all debugging tasks. For instance, sometimes you’ll want to peer into the contents of an object or array even if the data structure isn’t causing any particular problem or error. You can do this using Laravel’s dd() helper function, which will dump a variable’s contents to the browser and halt further script execution. To demonstrate the dd() function open the file app/Http/Controllers/WelcomeController.php and you’ll find single class method that looks like this:

public function index()
{
    return view('welcome');
}

for the moment just keep in mind that the Welcome controller’s index action executes when a user requests your web application’s home page. Modify this method to look like this:

public function index()
 {

     $items = array(
       'items' => ['Pack luggage', 'Go to airport', 'Arrive in San Juan']
     );                        
     dd($items); 

     return view('welcome');
}

Reload the home page in your browser and you should see the $items array contents dumped to the browser window as depicted in the below screenshot.

The Laravel Logger

While the dd() helper function is useful for quick evaluation of a variable’s contents, taking advantage of Laravel’s logging facilities is a more effective approach if you plan on repeatedly monitoring one or several data structures or events without necessarily interrupting script execution. Laravel will by default log error-related messages to the application log, located at storage/logs/laravel.log. Because Laravel’s logging features are managed by Monolog, you have a wide array of additional logging options at your disposal, including the ability to write log messages to this log file, set logging levels, send log output to the Firebug console via FirePHP, to the Chrome console using Chrome Logger, or even trigger alerts via e-mail, HipChat or Slack. Further, if you’re using the Laravel 4 Debugbar (introduced later in this chapter) you can easily peruse these messages from the Debugbar’s Messages tab.

Generating a custom log message is easy, done by embedding one of several available logging methods into the application, passing along the string or variable you’d like to log. Open the app/Http/Controllers/WelcomeController.php file and modify the index method to look like this:

public function index()
{

    $items = ['Pack luggage', 'Go to airport', 'Arrive in San Juan'];
    \Log::debug($items);

}

Save the changes, reload http://localhost:8000, and a log message similar to the following will be appended to storage/logs/laravel.log:

[2015-01-08 01:51:56] local.DEBUG: array (
  0 => 'Pack luggage',
  1 => 'Go to airport',
  2 => 'Arrive in San Juan',
)

The debug-level message is just one of several at your disposal. Among other levels are info, warning, error and critical, meaning you can use similarly named methods accordingly:

\Log::info('Just an informational message.');
\Log::warning('Something may be going wrong.');
\Log::error('Something is definitely going wrong.');
\Log::critical('Danger, Will Robinson! Danger!');

Integrating the Logger and FirePHP

When monitoring the log file it’s common practice to use the tail -f command (available on Linux and OS X) to view any log file changes in real time. You can however avoid the additional step of maintaining an additional terminal window for such purposes by instead sending the log messages to the Firebug console, allowing you to see the log messages alongside your application’s browser output. You’ll do this by integrating FirePHP.

You’ll first need to install the Firebug and FirePHP extensions, both of which are available via Mozilla’s official add-ons site. After restarting your browser, you can begin sending log messages directly to the Firebug console like so:

$monolog = \Log::getMonolog();

$items = ['Pack luggage', 'Go to airport', 'Arrive in San Juan'];

$monolog->pushHandler(new \Monolog\Handler\FirePHPHandler());

$monolog->addInfo('Log Message', array('items' => $items));

Once executed, the $items array will appear in your Firebug console as depicted in the below screenshot.

Using the Tinker Console

You’ll often want to test a small PHP snippet or experiment with manipulating a particular data structure, but creating and executing a PHP script for such purposes is kind of tedious. You can eliminate the additional overhead by instead using the tinker console, a command line-based window into your Laravel application. Open tinker by executing the following command from your application’s root directory:

$ php artisan tinker --env=local
Psy Shell v0.4.4 (PHP 5.5.21 — cli) by Justin Hileman
>>>

Notice tinker uses PsySH, a great interactive PHP console and debugger. PsySH is new to Laravel 5, and is a huge improvement over the previous console. Be sure to take some time perusing the feature list on the PsySH website to learn more about what this great utility can do. In the meantime, let’s get used to the interface:

>>> $items = ['Pack luggage', 'Go to airport', 'Arrive in San Juan'];
=> [
       "Pack luggage",
       "Go to airport",
       "Arrive in San Juan"
   ]

From here you could for instance learn more about how to sort an array using PHP’s sort() function:

>>> var_dump($items);
array(3) {
  [0]=>
  string(12) "Pack luggage"
  [1]=>
  string(13) "Go to airport"
  [2]=>
  string(18) "Arrive in San Juan"
}
=> null
>>> sort($items);
=> true
>>> $items;
=> [
       "Arrive in San Juan",
       "Go to airport",
       "Pack luggage"
   ]
>>>

After you’re done, type exit to exit the PsySH console:

>>> exit
Exit:  Goodbye.
$

PsySH can be incredibly useful for quickly experimenting with PHP snippets, and I’d imagine you’ll find yourself repeatedly returning to this indispensable tool. We’ll take advantage of PsySH throughout the book to get acquainted with various Laravel features.

Introducing the Laravel Debugbar

It can quickly become difficult to keep tabs on the many different events that are collectively responsible for assembling the application response. You’ll regularly want to monitor the status of database requests, routing definitions, view rendering, e-mail transmission and other activities. Fortunately, there exists a great utility called Laravel Debugbar that provides easy access to the status of these events and much more by straddling the bottom of your browser window (see below screenshot).

The Debugbar is visually similar to Firebug, consisting of multiple tabs that when clicked result in context-related information in a panel situated below the menu. These tabs include:

  • Messages: Use this tab to view log messages directed to the Debugbar. I’ll show you how to do this in a moment.
  • Timeline: This tab presents a summary of the time required to load the page.
  • Exceptions: This tab displays any exceptions thrown while processing the current request.
  • Views: This tab provides information about the various views used to render the page, including the layout.
  • Route: This tab presents information about the requested route, including the corresponding controller and action.
  • Queries: This tab lists the SQL queries executed in the process of serving the request.
  • Mails: This tab presents information about any e-mails delivered while processing the request.
  • Request: This tab lists information pertinent to the request, including the status code, request headers, response headers, and session attributes.

To install the Laravel Debugbar, execute the following command:

$ composer require barryvdh/laravel-debugbar
Using version ~2.0 for barryvdh/laravel-debugbar
./composer.json has been updated
...
Writing lock file
Generating autoload files
$ 

Next, add the following lines to the providers and aliases arrays to your config/app.php file, respectively:

 'providers' => [
     ...
     'Barryvdh\Debugbar\ServiceProvider'
 ], 

 ...

 'aliases' => [
    ...
    'Debugbar' => 'Barryvdh\Debugbar\Facade'
]

Save the changes and finally, install the package configuration to your config directory:

$ php artisan vendor:publish

While you don’t have to make any changes to this configuration file (found in config/debugbar.php), I suggest having a look at it to see what changes are available.

Reload the browser and you should see the Debugbar at the bottom of the page! Keep in mind the Debugbar will only render when used in conjunction with an endpoint that actually renders a view to the browser.

The Laravel Debugbar is tremendously useful as it provides easily accessible insight into several key aspects of your application. Additionally, you can use the Messages panel as a convenient location for viewing log messages. Logging to the Debugbar is incredibly easy, done using the Debugbar facade. Add the following line to the Welcome controller’s index action (app/Http/Controllers/WelcomeController.php):

\Debugbar::error('Something is definitely going wrong.');

Save the changes and reload the home page within the browser. Check the Debugbar’s Messages panel and you’ll see the logged message! Like the Laravel logger, the Laravel Debugbar supports the log levels defined in PSR-3, meaning methods for debug, info, notice, warning, error, critical, alert and emergency are available.

Testing Your Laravel Application with PHPUnit

Automated testing is a critical part of today’s web development workflow, and should not be ignored even for the most trivial of projects. Fortunately, the Laravel developers agree with this mindset and automatically include reference the PHPUnit package within every new Laravel project’s composer.json file:

"require-dev": {
  "phpunit/phpunit": "~4.0"
},

Running Your First Test

PHPUnit is a command-line tool that when installed via your project’s composer.json file is found in vendor/bin. Therefore to run PHPUnit you’ll execute it like this:

$ vendor/bin/phpunit --version
PHPUnit 4.7.2 by Sebastian Bergmann and contributors.

If you find typing vendor/bin/ to be annoying, consider making PHPUnit globally available, done using Composer’s global modifier. Rob Allen has written up a concise tutorial showing you how this is accomplished.

Inside the tests directory you’ll find a file named ExampleTest.php that includes a simple unit test. This test accesses the project home page, and determines whether a 200 status code is returned:

 <?php

 use Illuminate\Foundation\Testing\WithoutMiddleware;
 use Illuminate\Foundation\Testing\DatabaseMigrations;
 use Illuminate\Foundation\Testing\DatabaseTransactions;

 class ExampleTest extends TestCase
 {
     /**
      * A basic functional test example.
      *
      * @return void
      */
     public function testBasicExample()
     {
         $this->visit('/')
              ->see('Laravel 5');
     }
 }

This slick testing API is available as of Laravel 5.1. As you can see, the syntax is very readable and understandable. This example test accesses the project home page and confirms that the text Laravel 5 is found somewhere on the page. To run the test, just execute the phpunit command:

$ vendor/bin/phpunit
PHPUnit 4.7.2 by Sebastian Bergmann and contributors.

.

Time: 615 ms, Memory: 12.00Mb

OK (1 test, 2 assertions)

See that single period residing on the line by itself? That represents a passed test, in this case the test defined by the testBasicExample method. If the test failed, you would instead see an F for error. To see what a failed test looks like, open up app/Http/routes.php and comment out the following lines:

$router::get('/', function() {
  return view('welcome');
});

Save the changes and execute phpunit anew:

$ vendor/bin/phpunit
 PHPUnit 4.7.2 by Sebastian Bergmann and contributors.

 F

 Time: 403 ms, Memory: 11.75Mb

 There was 1 failure:

 1) ExampleTest::testBasicExample
 A request to [http://localhost] failed. Received status code [404].

This time the F is displayed, because the assertion defined in testBasicExample failed. Additionally, information pertaining to why the test failed is displayed. In the chapters to come we will explore other facets of PHPUnit and write plenty of additional tests.

Consider spending some time exploring the Laravel documentation to learn more about the syntax available to you. In any case, be sure to uncomment that route definition before moving on!

Reference