В этой мини-серии Nettuts + мы создадим веб-приложение с нуля, в то же время погрузившись в великолепную новую среду PHP, которая быстро набирает обороты и называется Laravel .
На этом уроке мы узнаем о некоторых очень полезных функциях Laravel: фильтрах, а также библиотеках проверки и файлов.
Рассмотрение
Добро пожаловать в наши веб-приложения с нуля с серией Laravel! Во втором уроке нашего мини-сериала мы узнали много нового о реализации ORM в Laravel:
- Немного истории о «Моделях»
- Что такое Eloquent ORM
- Как настроить конфигурацию базы данных Laravel
- Как создать свою первую модель Laravel
- Основные функции библиотек Auth и Input
- Использование Eloquent ORM в представлении
Если вы еще этого не видели, я призываю вас ознакомиться с первой и второй частью мини-серии — это значительно облегчит отслеживание, поскольку мы создаем наше тестовое приложение Instapics для каждой части.
Итак, начнем!
1 — Laravel Filters
В двух словах, фильтры — это функции, которые мы можем запускать на маршрутах before
или after
цикла запроса. Это особенно полезно для таких вещей, как аутентификация и регистрация. Чтобы зарегистрировать фильтр, нам нужно добавить что-то вроде следующего в файл application / rout.php :
1
2
3
4
|
Route::filter(‘myfilter’, function()
{
//What you want the filter to do
});
|
После того, как мы зарегистрировали фильтр, нам нужно прикрепить его к маршруту, например так:
1
2
3
4
|
Route::any(‘/’, array(‘before’ => ‘filter’, function()
{
//What you want the route to do
}));
|
В приведенном выше примере myfilter
сработает при всех запросах к странице индекса (т. myfilter
/ ). Допустим, мы хотели реализовать фильтр аутентификации для маршрута dashboard
:
01
02
03
04
05
06
07
08
09
10
11
|
Route::filter(‘auth’, function()
{
if(Auth::guest()) {
return Redirect::to(‘home’);
}
});
Route::any(‘dashboard’, array(‘before’ => ‘auth, function()
{
return View::make(‘dashboard’);
});
|
Приведенный выше код перенаправит все неаутентифицированные запросы на маршрут панели мониторинга к домашнему маршруту.
Глобальные фильтры
По умолчанию Laravel включает два фильтра, before
и after
, которые запускаются до и после каждого запроса к приложению. Обычно это место, где вы размещаете такие вещи, как ведение журнала запросов, добавление глобальных активов или запуск глобальных событий. Например:
1
2
3
4
|
Route::filter(‘after’, function($response)
{
Log::write(‘request’, ‘Request finished on ‘ . date(‘d M, Y — h:i:sA’) . ‘.\n\nRequest Information:\n ‘. var_export(Input::get(), true));
});
|
Это записывает сообщение журнала типа request
журнал приложения и перечисляет любые входные данные запроса.
Группы маршрутов
Если вы обнаружите, что применяете один и тот же фильтр к нескольким маршрутам, вы можете использовать группы маршрутов, чтобы сгруппировать их все вместе и уменьшить количество повторений кода:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
Route::filter(‘admin_auth’, function()
{
if(Auth::guest() || !Auth::user()->isAdmin()) {
return Redirect::to(‘home’);
}
});
Route::group(array(‘before’ => ‘admin_auth’), function()
{
Route::get(‘admin’, function()
{
return View::make(‘admin’);
});
Route::get(‘useradmin’, function()
{
return View::make(‘useradmin’);
});
});
|
Контроллер Фильтры
Для приложений (таких как наши собственные Instapics ), которые используют контроллеры, мы можем применять фильтры, используя функцию $this->filter()
в конструкторе контроллера:
1
2
3
4
|
public function __construct()
{
$this->filter(‘before’, ‘auth’);
}
|
Эти фильтры, такие как маршруты, также можно настроить для применения только к определенным HTTP-глаголам и конкретным действиям контроллера:
1
2
3
4
5
6
7
8
|
public function __construct()
{
//call ‘log_download’ filter for all download/file GET requests
$this->filter(‘after’, ‘log_download’)->only(array(‘file’))->on(‘get’);
//call the ‘auth_download’ filter for all download/* requests, except for the ‘queue’ action
$this->filter(‘before’, ‘auth_download’)->except(array(‘queue’));
}
|
2 — Валидация Ларавела
Встроенная в Laravel валидация позволяет легко применять валидацию к любому массиву значений, в частности, к вводу формы. Для этого вам просто нужно построить два массива:
- $ input — это ассоциативный массив значений, которые вы хотите проверить.
- $ rules — это ассоциативный массив (с ключами, совпадающими с массивом $ input), в котором перечислены правила проверки.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
//Getting our input from the Input library
$input = Input::all();
//Create our validation rules
$rules = array(
’email’ => ‘required|email|unique:users’,
‘password’ => ‘required’
);
//Getting a $validation instance for our error checking
$validation = Validator::make($input, $rules);
//Check if the validation succeeded
if( $validation->fails() ) {
//do something with the error messages from the $validation instance
$validation->errors;
}
|
Правила валидации
Ниже приведен список правил проверки, которые можно использовать с библиотекой проверки Laravel. Как и в примере выше, вы можете смешивать и сопоставлять их, разделяя их с помощью трубы (» | «):
-
required
— значение должно присутствовать во входном массиве1’email’ => ‘required’ -
alpha
— значение должно состоять только из букв алфавита1‘full_name’ => ‘alpha’ -
alpha_num
— значение должно состоять только из буквенно-цифровых символов1‘username’ => ‘alpha_num’ -
alpha_dash
— значение должно состоять только из буквенно-цифровых символов, тире и / или подчеркиваний1‘user_name’ => ‘alpha_dash’ -
size
— значение должно иметь только заданную длину или должно быть равно, если числовой1‘api_key’ => ‘size:10’1‘order_count’ => ‘size:10’ -
between
— значение включительно между указанным диапазоном1‘order_count’ => ‘between:1,100’ -
min
— значение как минимум заданное1‘order_count’ => ‘min:1’ -
max
— значение равно или меньше заданного1‘order_count’ => ‘max:100’ -
numeric
— значение числовое1‘order_count’ => ‘numeric’ -
integer
— значение является целым числом1‘order_count’ => ‘integer’ -
in
— значение содержится в данном1‘tshirt_size’ => ‘in:xsmall,small,medium,large,xlarge’ -
not_in
— значение не в данном1‘tshirt_size’ => ‘not_in:xsmall,xlarge’ -
confirmed
— проверит, существует лиkey _confirmation
и равен ли он значению1‘password’ => ‘confirmed’Это проверит, существует ли значение
password_confirmation
и равно ли оноpassword
-
accepted
— это проверит, установлено ли значение «да» или 1. Полезно для флажков1‘terms_of_service’ => ‘accepted’ -
same
— значение совпадает со значением данного атрибута1‘password’ => ‘same:confirm_password’ -
different
— значение должно отличаться от значения данного атрибута1‘password’ => ‘different:old_password’ -
match
— значение должно соответствовать заданному регулярному выражению1‘user_name’ => ‘match:/[a-zA-Z0-9]*/’ -
unique
— проверяет уникальность значения в данной таблице.1‘user_name’ => ‘unique:users’Данный столбец также принимается, если имя столбца не совпадает с именем атрибута.
123//if the column in the users table is username,//we can provide this in the given like so:‘user_name’ => ‘unique:users,username’Есть моменты, когда мы хотим проверить уникальность, но игнорируем определенную запись (обычно запись, связанную с текущим пользователем). Мы можем сделать это, добавив третье значение, которое должно быть идентификатором этой записи в таблице.
12//ID 10 is the record ID of the current user‘user_name’ => ‘unique:users,user_name,10’ -
exists
— значение должно существовать в таблице1‘category’ => ‘exists:categories’Это также принимает второе значение, если мы хотим изменить имя столбца для проверки.
1‘category’ => ‘exists:categories,category_name’ -
before
— значение должно быть датой до указанной даты1‘publish_date’ => ‘before:2012-07-14’ -
after
— значение должно быть датой после данной даты1‘publish_date’ => ‘after:2012-07-14’ -
email
— значение должно быть в правильном формате электронной почты1‘subscriber_email’ => ’email’ -
url
— значение в правильном формате URL1‘github_profile’ => ‘url’ -
active_url
— значение в правильном формате URL и активно1‘github_profile’ => ‘active_url’ -
mimes
— проверяет тип mime загруженного файла. Вы можете использовать любое значение mime-type из файла config / mimes.php1‘avatar’ => ‘mimes:jpg,gif,png,bmp’ -
image
— файл должен быть изображением1‘avatar’ => ‘image’Вы также можете использовать
max
валидатор здесь, чтобы проверить размер файла в килобайтах1‘avatar’ => ‘image|max:100’
Обработка ошибок
Когда вы вызываете метод Validator->fails()
или Validator->passes()
, библиотека собирает все ошибки в классе, который доступен через Validator->errors
. После этого вы сможете получить эти ошибки с помощью некоторых функций в классе errors
. Laravel предоставляет некоторые интересные функции для автоматизации обработки ошибок, которые подходят для большинства сценариев POST / REDIRECT / GET:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
class Register_Controller extends Base_Controller
{
public $restful = true;
public function get_index()
{
return View::make(‘register.index’);
}
public function post_index()
{
$rules = array(
’email’ => ‘required|email|unique:users’,
‘password’ => ‘confirmed’
);
$validation = Validator::make(Input::get(), $rules);
if( $validation->fails() ) {
//Send the $validation object to the redirected page
return Redirect::to(‘register’)->with_errors($validation);
}
}
}
|
Здесь мы используем метод with_errors
для библиотеки Redirect
. Это автоматически связывает переменную $errors
в представлении, куда бы мы ни перенаправляли — в данном случае это страница register/index
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
<form>
{{— $errors variable passed via with_errors —}}
@if ($errors->has(’email’))
@foreach ($errors->get(’email’, ‘<p class=»error-message»>:message</p>’) as $email_error)
{{ $email_error }}
@endforeach
@endif
<label for=»email»>Email:</label>
<input type=»email» name=»email» placeholder=»Enter your email address here» />
@if ($errors->has(‘password’))
@foreach ($errors->get(‘password’, ‘<p class=»error-message»>:message</p>’) as $password_error)
{{ $password_error }}
@endif
<label for=»password»>Password:</label>
<input type=»password» name=»password» placeholder=»Enter your password here» />
<label for=»password_confirmation»>Confirm Password:</label>
<input type=»password» name=»password_confirmation» placeholder=»Re-type your password here» />
</form>
|
В файле представления мы используем метод $errors->has()
чтобы проверить, существует ли ошибка для указанного поля. Если это так, мы используем метод $errors->get()
для отображения сообщений об ошибках. Второй параметр в этом методе можно использовать для предоставления шаблона для отображения сообщения об ошибке.
Пользовательские сообщения об ошибках
Поскольку большинство людей хотели бы изменить сообщения об ошибках для Laravel, чтобы они соответствовали брендингу или языку их приложения, библиотека Validation также позволяет настраивать сообщения об ошибках, которые генерируются путем простого добавления массива $messages
в вызов функции Validate::make
:
01
02
03
04
05
06
07
08
09
10
11
12
|
$rules = array(
’email’ => ‘required|email|unique:users’,
‘password’ => ‘confirmed’
);
$messages = array(
’email_required’ => ‘Please provide an email address’,
’email_email’ => ‘Please provide a valid email address’,
’email_unique’ => ‘The email address you provided is already being used’,
‘password_confirmed’ => ‘Your password confirmation did not match your password.’
);
$validation = Validator::make(Input::get(), $rules, $messages);
|
Есть два способа создать массив $messages
:
- На основе правил — вы можете предоставить настраиваемое сообщение для всех полей, проверенных по определенному правилу. Например:
1234567$messages = array(‘required’ => ‘The :attribute field is required.’,‘same’ => ‘The :attribute and :other must match.’,‘size’ => ‘The :attribute must be exactly :size.’,‘between’ => ‘The :attribute must be between :min — :max.’,‘in’ => ‘The :attribute must be one of the following types: :values’,);
Это изменит сообщения об ошибках по умолчанию для всех полей, имеющих
required, same, size, between and in
правилах. Здесь мы также видим, что Laravel использует заполнители для замены определенных значений в сообщении об ошибке.:attribute
изменится на атрибут поля (без подчеркивания), для которого он.:other
используется для тогоsame
правила, которое ссылается на другой атрибут, которому он должен соответствовать.:size
относится к определенному размеру в параметрах правила.:min
и:max
— это минимальное и максимальное значения, а:values
— список значений, которые мы указали, в которых должно быть указано значение поля. - На основе атрибутов — с другой стороны, вы также можете предоставить настраиваемое сообщение для определенного атрибута в определенном правиле. Взяв наш пример сверху:
123456$messages = array(’email_required’ => ‘Please provide an email address’,’email_email’ => ‘Please provide a valid email address’,’email_unique’ => ‘The email address you provided is already being used’,‘password_confirmed’ => ‘Your password confirmation did not match your password.’);
email_required
— это сообщение об ошибке, которое используется, когда атрибутemail
не соответствуетrequired
правилу,email_email
— это сообщение об ошибке, которое используется, когдаemail
не соответствует правилуemail
и т. д.
Однако, если вы постоянно воссоздаете одни и те же пользовательские сообщения, было бы проще просто указать пользовательские сообщения об ошибках глобально. Вы можете сделать это, отредактировав файл application / langauge / en / validation.php и отредактировав найденный там custom
массив:
01
02
03
04
05
06
07
08
09
10
|
…
…
‘custom’ => array(
’email_required’ => ‘Please provide an email address’,
’email_email’ => ‘Please provide a valid email address’,
’email_unique’ => ‘The email address you provided is already being used’,
‘password_confirmed’ => ‘Your password confirmation did not match your password.’
);
…
…
|
3 — Файлы Laravel
Обработка загрузки файлов
Библиотека Files Laravel упрощает обработку загрузки файлов с помощью метода Input::upload
, который является простой оболочкой для PHP-функции move_uploaded_file
:
1
|
Input::upload(‘input_name’, ‘directory/to/save/file’, ‘filename.extension’);
|
Для проверки загрузки файлов вы можете использовать библиотеку Validator
мы обсуждали выше, например:
1
2
3
4
5
6
7
8
9
|
$input = array(
‘upload’ => Input::file(‘upload’)
);
$rules = array(
‘upload’ => ‘mimes:zip,rar|max:500’
);
$validator = Validator::make($input, $rules);
|
Управление файлами
Библиотека Files также имеет несколько методов манипулирования файлами, например:
1
2
3
4
5
6
7
8
|
//Get a file
$data = File::get(‘path/file.extension’);
//Write a file
File::put(‘path/file.extension’, $data);
//Appending to a file
File::append(‘path/file.extension’, $data);
|
Функции, связанные с файлами
Laravel также предоставляет некоторые общие функции, связанные с файлами, которые можно использовать в вашем коде. Например, метод File::extension
возвращает расширение строки имени файла:
1
2
|
//This will return ‘zip’
File::extension(‘data.zip’);
|
Функция File::is
проверяет, принадлежит ли файл определенного типа. Обратите внимание, что это не просто проверяет расширение файла, но использует расширение Fileinfo
PHP для чтения фактического содержимого файла. Это полезно для определения того, что файл действительно имеет правильный тип файла:
1
2
|
//Returns true if the file is a zip file, false if otherwise
File::is(‘zip’, ‘path/file.zip’);
|
Список совместимых расширений можно увидеть в файле application / config / mimes.php .
Говоря о типах MIME, вы также можете использовать функцию File::mime
для получения MIME-типов расширения. Возвращаемый тип mime основан на том же файле mimes.php :
1
2
|
//This will return image/png
File::mime(‘png’)
|
File::cpdir
и File::rmdir
могут копировать и удалять каталог соответственно.
1
2
3
4
|
File::cpdir(‘directory/to/copy’, ‘destination/directory’);
//File::rmdir is a recursive delete, so it will delete all files and folders inside the directory.
File::rmdir(‘directory/to/delete’);
|
Теперь, когда мы узнали все о фильтрах , библиотеке валидации и библиотеке файлов , давайте реализуем их в нашем приложении Instapics .
Шаг 1 Создайте фильтр auth
Добавить фильтры в Base_Controller
Давайте начнем с того, что наши пользователи смогут видеть только аутентифицированные страницы, создав фильтр авторизации, который запускается перед всеми запросами. Поскольку мы используем маршрутизацию на основе контроллера, нам необходимо настроить наши фильтры в нашем контроллере. Давайте поместим фильтры в метод __construct
Base_Controller
чтобы убедиться, что фильтр auth
работает на всех контроллерах, которые его расширяют. Пока мы это делаем, давайте добавим nonauth
фильтр, чтобы люди могли посещать только определенные страницы, когда они не nonauth
проверку подлинности:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
class Base_Controller extends Controller {
public function __construct()
{
//Assets
Asset::add(‘jquery’, ‘js/jquery-1.7.2.min.js’);
Asset::add(‘bootstrap-js’, ‘js/bootstrap.min.js’);
Asset::add(‘bootstrap-css’, ‘css/bootstrap.min.css’);
Asset::add(‘bootstrap-css-responsive’, ‘css/bootstrap-responsive.min.css’, ‘bootstrap-css’);
Asset::add(‘style’, ‘css/style.css’);
parent::__construct();
//Filters
$class = get_called_class();
switch($class) {
case ‘Home_Controller’:
$this->filter(‘before’, ‘nonauth’);
break;
case ‘User_Controller’:
$this->filter(‘before’, ‘nonauth’)->only(array(‘authenticate’));
$this->filter(‘before’, ‘auth’)->only(array(‘logout’));
break;
default:
$this->filter(‘before’, ‘auth’);
break;
}
}
|
Здесь мы определяем, что для любых запросов к home
маршруту потребуется неаутентифицированный пользователь, что хорошо, поскольку именно здесь находится экран входа в систему. Любой другой запрос по умолчанию будет требовать аутентифицированного пользователя. Для User_Controller
у нас фактически есть два отдельных метода, которые требуют как неаутентифицированных пользователей (аутентификация), так и аутентифицированных пользователей (выход из системы), поэтому мы используем only
метод, чтобы указать, к каким действиям контроллера применяются фильтры.
Создайте определения фильтров в routes.php
Теперь откройте application / rout.php , где мы определим фильтры auth
и nonauth
. Обратите внимание, что у вас уже может быть существующее определение фильтра auth
поэтому просто замените его на приведенное ниже:
1
2
3
4
5
6
7
8
9
|
Route::filter(‘auth’, function()
{
if (Auth::guest()) return Redirect::to(‘home’);
});
Route::filter(‘nonauth’, function()
{
if (Auth::guest() == false) return Redirect::to(‘dashboard’);
});
|
В фильтре auth
мы проверяем, прошел ли пользователь аутентификацию с помощью библиотеки Auth
. Если пользователь не аутентифицирован, мы перенаправляем его обратно на home
маршрут, где находится экран входа, в противном случае ему разрешается продолжить. То же самое с фильтром nonauth
— проверьте, аутентифицирован ли пользователь, если он есть, затем перенаправьте его на панель мониторинга.
Шаг 2 Реализация пользовательских загрузок
Создать форму загрузки фото
Теперь, когда мы знаем немного больше о том, как обрабатывать загрузку файлов в Laravel, давайте начнем реализовывать одну из основных функций Instapics — загрузку фотографий. Начните с создания папки с именем application / views / plugins и внутри нее создайте файл представления Blade с именем upload_modal.blade.php . Вставьте следующий HTML-код:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
<div class=»modal hide» id=»upload_modal»>
<div class=»modal-header»>
<button type=»button» class=»close» data-dismiss=»modal»>×</button>
<h3>Upload a new Instapic</h3>
</div>
<div class=»modal-body»>
<form method=»POST» action=»{{ URL::to(‘photo/upload’) }}» id=»upload_modal_form» enctype=»multipart/form-data»>
<label for=»photo»>Photo</label>
<input type=»file» placeholder=»Choose a photo to upload» name=»photo» id=»photo» />
<label for=»description»>Description</label>
<textarea placeholder=»Describe your photo in a few sentences» name=»description» id=»description» class=»span5″></textarea>
</form>
</div>
<div class=»modal-footer»>
<a href=»#» class=»btn» data-dismiss=»modal»>Cancel</a>
<button type=»button» onclick=»$(‘#upload_modal_form’).submit();»
</div>
</div>
|
Создать кнопку триггера
Давайте запустим эту модальную форму кнопкой — добавьте это в application / views / layouts / main.blade.php после div .nav-collapse
:
01
02
03
04
05
06
07
08
09
10
11
12
|
<div class=»nav-collapse»>
<ul class=»nav»>
@section(‘navigation’)
<li class=»active»><a href=»home»>Home</a></li>
@yield_section
</ul>
</div><!—/.nav-collapse —>
@section(‘post_navigation’)
@if (Auth::check())
@include(‘plugins.loggedin_postnav’)
@endif
@yield_section
|
Здесь мы включаем файл представления с именем loggedin_postnav
если пользователь вошел в систему. Здесь мы добавим кнопку для модальной формы загрузки. В том же файле добавьте это после div .container
:
01
02
03
04
05
06
07
08
09
10
11
12
|
<div class=»container»>
@yield(‘content’)
<hr>
<footer>
<p>©
</footer>
</div> <!— /container —>
@section(‘modals’)
@if (Auth::check())
@include(‘plugins.upload_modal’)
@endif
@yield_section
|
Здесь мы включаем HTML upload_modal
. Тем не менее, мы должны убедиться, что пользователь не вошел в систему, прежде чем включать этот HTML-файл, поскольку, как и триггер кнопки, это действительно не потребуется, если пользователь не аутентифицирован.
Теперь создайте приложение / views / plugins / loggedin_postnav.blade.php
1
2
3
|
<div class=»btn-group pull-right»>
<button type=»button» class=»btn btn-primary» onclick=»$(‘#upload_modal’).modal({backdrop: ‘static’});»><i class=»icon-plus-sign icon-white»></i> Upload Instapic</button>
</div>
|
Обновите страницу, и вы должны увидеть новую кнопку загрузки — нажмите на нее, чтобы увидеть, что она работает!
Подключите форму к соответствующему контроллеру
Теперь, когда у нас есть работающий интерфейс, давайте начнем работать с серверной частью формы. Создайте приложение / controllers / photo.php и вставьте следующий код для контроллера:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
class Photo_Controller extends Base_Controller
{
public function action_upload()
{
$input = Input::all();
$extension = File::extension($input[‘photo’][‘name’]);
$directory = path(‘public’).’uploads/’.sha1(Auth::user()->id);
$filename = sha1(Auth::user()->id.time()).».{$extension}»;
$upload_success = Input::upload(‘photo’, $directory, $filename);
if( $upload_success ) {
Session::flash(‘status_success’, ‘Successfully uploaded new Instapic’);
} else {
Session::flash(‘status_error’, ‘An error occurred while uploading new Instapic — please try again.’);
}
if( $upload_success ) {
$photo = new Photo(array(
‘location’ => URL::to(‘uploads/’.sha1(Auth::user()->id).’/’.$filename),
‘description’ => $input[‘description’]
));
Auth::user()->photos()->insert($photo);
}
return Redirect::to(‘dashboard’);
}
}
|
Попробуйте — вы сможете начать загружать новые Instapics.
Добавить подтверждение в форму загрузки
Давайте добавим несколько правил проверки, чтобы убедиться, что пользователь отправляет только правильные данные. Обновите контроллер следующим:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
class Photo_Controller extends Base_Controller
{
public function action_upload()
{
$input = Input::all();
if( isset($input[‘description’]) ) {
$input[‘description’] = filter_var($input[‘description’], FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);
}
$rules = array(
‘photo’ => ‘required|image|max:500’, //photo upload must be an image and must not exceed 500kb
‘description’ => ‘required’ //description is required
);
$validation = Validator::make($input, $rules);
if( $validation->fails() ) {
return Redirect::to(‘dashboard’)->with_errors($validation);
}
$extension = File::extension($input[‘photo’][‘name’]);
$directory = path(‘public’).’uploads/’.sha1(Auth::user()->id);
$filename = sha1(Auth::user()->id.time()).».{$extension}»;
$upload_success = Input::upload(‘photo’, $directory, $filename);
if( $upload_success ) {
$photo = new Photo(array(
‘location’ => URL::to(‘uploads/’.sha1(Auth::user()->id).’/’.$filename),
‘description’ => $input[‘description’]
));
Auth::user()->photos()->insert($photo);
Session::flash(‘status_success’, ‘Successfully uploaded your new Instapic’);
} else {
Session::flash(‘status_error’, ‘An error occurred while uploading your new Instapic — please try again.’);
}
return Redirect::to(‘dashboard’);
}
}
|
Посмотрите, как мы проверяем ввод? Мы удостоверяемся, что фотография присутствует, изображение и меньше, чем 500kb. Мы также следим за тем, чтобы описание присутствовало после санации. Мы пока не сможем увидеть наши сообщения об ошибках, поэтому давайте исправим это, добавив немного HTML для отображения наших сообщений об ошибках. Откройте application / views / layouts / main.blade.php и добавьте следующее в div .container :
1
2
3
4
5
6
7
8
|
<div class=»container»>
@include(‘plugins.status’)
@yield(‘content’)
<hr>
<footer>
<p>©
</footer>
</div> <!— /container —>
|
Теперь создайте приложение / views / plugins / status.blade.php . Это где мы будем отображать фактические сообщения об ошибках. Мы также добавим поддержку сообщений о состоянии сеанса (например, тот, который мы используем при проверке $upload_success
в коде контроллера Photos
):
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
@if (isset($errors) && count($errors->all()) > 0)
<div class=»alert alert-error»>
<a class=»close» data-dismiss=»alert» href=»#»>×</a>
<h4 class=»alert-heading»>Oh Snap!</h4>
<ul>
@foreach ($errors->all(‘<li>:message</li>’) as $message)
{{ $message }}
@endforeach
</ul>
</div>
@elseif (!is_null(Session::get(‘status_error’)))
<div class=»alert alert-error»>
<a class=»close» data-dismiss=»alert» href=»#»>×</a>
<h4 class=»alert-heading»>Oh Snap!</h4>
@if (is_array(Session::get(‘status_error’)))
<ul>
@foreach (Session::get(‘status_error’) as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@else
{{ Session::get(‘status_error’) }}
@endif
</div>
@endif
@if (!is_null(Session::get(‘status_success’)))
<div class=»alert alert-success»>
<a class=»close» data-dismiss=»alert» href=»#»>×</a>
<h4 class=»alert-heading»>Success!</h4>
@if (is_array(Session::get(‘status_success’)))
<ul>
@foreach (Session::get(‘status_success’) as $success)
<li>{{ $success }}</li>
@endforeach
</ul>
@else
{{ Session::get(‘status_success’) }}
@endif
</div>
@endif
|
Попробуйте вызвать ошибки в форме загрузки прямо сейчас, отправив файл без выбора или без описания (так как оба требуются). Вы должны увидеть сообщения об ошибках, отображаемые сверху:
Шаг 3 Добавьте валидацию в форму регистрации и входа
Теперь, когда мы знаем, как использовать библиотеку Laravel Validation , давайте вернемся к нашей первой форме — форме входа и регистрации. На данный момент мы просто используем echo
чтобы увидеть, что вход в систему или регистрация не пройдены — давайте заменим это на правильную проверку. Откройте application / controllers / user.php и обновите его так:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
class User_Controller extends Base_Controller
{
public function action_authenticate()
{
$email = Input::get(’email’);
$password = Input::get(‘password’);
$new_user = Input::get(‘new_user’, ‘off’);
$input = array(
’email’ => $email,
‘password’ => $password
);
if( $new_user == ‘on’ ) {
$rules = array(
’email’ => ‘required|email|unique:users’,
‘password’ => ‘required’
);
$validation = Validator::make($input, $rules);
if( $validation->fails() ) {
return Redirect::to(‘home’)->with_errors($validation);
}
try {
$user = new User();
$user->email = $email;
$user->password = Hash::make($password);
$user->save();
Auth::login($user);
return Redirect::to(‘dashboard’);
} catch( Exception $e ) {
Session::flash(‘status_error’, ‘An error occurred while creating a new account — please try again.’);
return Redirect::to(‘home’);
}
} else {
$rules = array(
’email’ => ‘required|email|exists:users’,
‘password’ => ‘required’
);
$validation = Validator::make($input, $rules);
if( $validation->fails() ) {
return Redirect::to(‘home’)->with_errors($validation);
}
$credentials = array(
‘username’ => $email,
‘password’ => $password
);
if( Auth::attempt($credentials)) {
return Redirect::to(‘dashboard’);
} else {
Session::flash(‘status_error’, ‘Your email or password is invalid — please try again.’);
return Redirect::to(‘home’);
}
}
}
public function action_logout()
{
Auth::logout();
Redirect::to(‘home/index’);
}
}
|
Поскольку мы сделали наши сообщения о статусе модульными, нам даже не нужно писать дополнительный HTML, чтобы увидеть сообщения об ошибках в действии! Просто попробуйте!
Вывод
В третьем уроке из нашей серии Laravel мы узнали:
- Как, когда и где использовать Laravel Filters
- Как использовать библиотеку валидации Laravel и как обрабатывать ошибки библиотеки валидации .
- Как управлять файлами в Laravel с помощью библиотеки Files
Laravel поставляется с множеством этих небольших функций и библиотек, которые, хотя и реализуются другими способами, становятся проще и проще (например, загрузка файлов в одну строку!) Благодаря использованию выразительной природы Laravel. Именно эти небольшие, экономящие время библиотеки добавляют и со временем экономят массу потраченного времени на переписывание кода.
Далее в наших веб-приложениях из серии Scratch with Laravel мы узнаем больше о событиях, миграциях и некотором расширенном использовании Eloquent ORM!
Что вы думаете о библиотеках Laravel, обсуждаемых в руководстве? Это то, что вы считаете полезным? Дай мне знать в комментариях! И, если вы являетесь участником Tuts + Premium , следите за обновлениями нашего предстоящего курса Laravel Essentials!