二、使用表单和收集输入

在本章中,我们将介绍:

  • 创建简单的表单
  • 收集表单输入以显示在另一个页面上
  • 验证用户输入
  • 创建文件上传程序
  • 正在验证文件上传
  • 创建自定义错误消息
  • 在表单中添加“蜜罐”
  • 使用编校器上传图像
  • 用 Jcrop 裁剪图像
  • 创建自动完成文本输入
  • 制作验证码风格的垃圾邮件捕捉器

简介

在本章中,我们将学习在 Laravel 中使用表单,以及如何完成一些典型的任务。我们将从一些简单的表单验证和文件上传开始,然后将一些前端工具,比如密文和 jCrop,合并到 Laravel 中。

创建一个简单的表单

任何 web 应用最基本的方面之一就是表单。Laravel 提供了为我们的表单构建 HTML 的简单方法。

做好准备

首先,我们需要一个全新的 Laravel 安装。

怎么做...

要完成这个配方,请遵循以下步骤:

  1. app/views文件夹中,新建一个userform.php文件。
  2. routes.php中,创建一条路径来加载视图:

    php Route::get(userform, function() { return View::make('userform'); });

  3. userform.php视图中,使用以下代码创建表单:

    php <h1>User Info</h1> <?= Form::open() ?> <?= Form::label('username', 'Username') ?> <?= Form::text('username') ?> <br> <?= Form::label('password', 'Password') ?> <?= Form::password('password') ?> <br> <?= Form::label('color', 'Favorite Color') ?> <?= Form::select('color', array('red' => 'red', 'green' =>'green', 'blue' => 'blue')) ?> <br> <?= Form::submit('Send it!') ?> <?= Form::close() ?>

通过进入http://{your-server}/userform(其中{your-server}是服务器的名称)在网页中查看您的表单。

它是如何工作的...

对于这个任务,我们使用 Laravel 的内置Form类创建了一个简单的表单。这允许我们用最少的代码轻松地创建表单元素,并且符合 W3C(万维网联盟)标准。

首先,我们打开表单。Laravel 自动创建<form> html,包括动作、方法和 accept-charset 参数。没有传入选项时,默认动作为当前 URL,默认方法为POST,,字符集取自应用配置文件。

接下来,我们创建普通文本和密码输入字段,以及它们的标签。标签中的第一个参数是文本字段的名称,第二个参数是要打印的实际文本。在表单生成器中,标签应该出现在实际的表单输入之前。

表单选择需要第二个参数,即下拉框中值的数组。在这个例子中,我们使用'key' => 'value'语法创建了一个数组。如果我们想创建选项组,我们只需要创建嵌套数组。

最后,我们创建我们的提交按钮并关闭表单。

还有更多...

Laravel 的大多数表单方法还可以包含默认值和自定义属性(类、标识等)的参数。如果我们不想使用特定的方法,我们也可以将Form::input()用于许多字段。例如,我们可以让Form::input('submit', NULL, 'Send it!')创建一个提交按钮。

另见

  • 采集表格输入显示在另一页配方上

收集表单输入以显示在另一个页面上

用户提交表单后,我们需要能够获取该信息并将其传递到另一个页面。这个食谱展示了我们如何使用 Laravel 的内置方法来处理我们的 POST 数据。

做好准备

我们需要从创建简单表单部分设置的简单表单。

怎么做...

按照以下步骤完成该配方:

  1. 创建一个路由来处理来自表单的开机自检数据:

    ```php Route::post('userform', function() { // Process the data here return Redirect::to('userresults')- >withInput(Input::only('username', 'color')); });

    ```

  2. 创建要重定向到的路由,并显示数据:

    ```php Route::get('userresults', function() { return 'Your username is: ' . Input::old('username') . '
    Your favorite color is: ' . Input::old('color'); });

    ```

它是如何工作的...

在我们简单的表单中,我们将数据发布回同一个网址,因此我们需要创建一个使用相同路径接受POST的路由。这是我们对数据进行任何处理的地方,包括保存到数据库或验证输入。

在这种情况下,我们只想将数据传递到下一页。有许多方法可以实现这一点。例如,我们可以使用Input类的 flashOnly()方法:

Route::post('userform', function()
{
    Input::flashOnly('username', 'color');
    return Redirect::to('userresults');
});

然而,我们使用的是 Laravel 提供的快捷方式,并且只传递我们要求的三个表单域中的两个。

在下一页,我们使用Input::old()显示闪烁的输入。

另见

  • 创建一个简单的配方

验证用户输入

在大多数 web 应用中,处理表单需要某些表单字段。我们还希望确保所有电子邮件地址的格式正确,或者输入必须有一定数量的字符。使用 Laravel 的 Validator类,我们可以检查这些规则,让用户知道是否有不正确的地方。

做好准备

对于这个食谱,我们只需要一个标准安装的 Laravel。

怎么做...

要完成此配方,请遵循以下步骤:

  1. 创建保存表单的路线:

    php Route::get('userform', function() { return View::make('userform'); });

  2. 创建一个名为userform.php的视图,并添加一个表单:

    php <h1>User Info</h1> <?php $messages = $errors->all('<pstyle="color:red">:message</p>') ?> <?php foreach ($messages as $msg) { echo $msg; } ?> <?= Form::open() ?> <?= Form::label('email', 'Email') ?> <?= Form::text('email', Input::old('email')) ?> <br> <?= Form::label('username', 'Username') ?> <?= Form::text('username', Input::old('username')) ?> <br> <?= Form::label('password', 'Password') ?> <?= Form::password('password') ?> <br> <?= Form::label('password_confirm', 'Retype your Password')?> <?= Form::password('password_confirm') ?> <br> <?= Form::label('color', 'Favorite Color') ?> <?= Form::select('color', array('red' => 'red', 'green' =>'green', 'blue' => 'blue'), Input::old('color')) ?> <br> <?= Form::submit('Send it!') ?> <?php echo Form::close() ?>

  3. 创建一条处理我们的POST数据并验证它的路线:

    ```php Route::post('userform', function() { $rules = array( 'email' => 'required|email|different:username', 'username' => 'required|min:6', 'password' => 'required|same:password_confirm' ); $validation = Validator::make(Input::all(), $rules);

    if ($validation->fails())
    {
        return Redirect::to('userform')-
            >withErrors($validation)->withInput();
    }
    
    return Redirect::to('userresults')->withInput();
    

    });

    ```

  4. 创建处理成功表单提交的路线:

    php Route::get('userresults', function() { return dd(Input::old()); });

它是如何工作的...

在我们的表单页面中,我们首先检查是否有任何错误,如果发现则显示它们。在错误内部,我们可以为每个错误消息设置默认样式。我们还可以选择使用$errors->get('email')检查和显示单个字段的错误。如果检测到闪回错误,$errors变量由 Laravel 自动创建。

接下来,我们创建表单。在表单元素的最后一个参数中,我们得到了Input::old(),如果验证失败,我们使用它来存储之前的输入。这样,用户就不需要一直填写整个表单。

然后,我们创建一条路径,在那里发布表单,并设置我们的验证规则。在这种情况下,我们对emailusernamepassword使用所需的规则,以确保在这些字段中键入了内容。

email字段也得到email规则,使用 PHP 内置的filter_var函数的FILTER_VALIDATE_EMAIL过滤器。email场也不能和username场一样。username字段使用大小验证来检查至少六个字符。然后password字段检查password_confirm字段的值,并确保它们相同。

然后,我们创建验证器并传入所有表单数据。如果不符合这些规则中的任何一条,我们将用户导航回表单,并发回任何验证错误消息以及原始表单输入。

如果验证通过,我们使用 Laravel 的dd()助手函数进入下一页,该函数使用var_dump()在页面上显示表单值。

另见

  • 创建简单表单配方

创建文件上传器

有时我们希望用户将文件上传到我们的服务器。这个食谱展示了 Laravel 如何通过网络表单处理文件上传。

做好准备

要创建一个文件上传器,我们需要安装一个标准版本的 Laravel。

怎么做...

要完成此配方,请遵循以下步骤:

  1. 在我们的routes.php文件中创建一个路径来保存表单:

    php Route::get('fileform', function() { return View::make('fileform'); });

  2. 在我们的app/views目录中创建fileform.php视图:

    php <h1>File Upload</h1> <?= Form::open(array('files' => TRUE)) ?> <?= Form::label('myfile', 'My File') ?> <br> <?= Form::file('myfile') ?> <br> <?= Form::submit('Send it!') ?> <?= Form::close() ?>

  3. 创建上传和保存文件的路线:

    php Route::post('fileform', function() { $file = Input::file('myfile'); $ext = $file->guessExtension(); if ($file->move('files', 'newfilename.' . $ext)) { return 'Success'; } else { return 'Error'; } });

它是如何工作的...

在我们的视图中,我们使用Form::open ()并传入一个带有'files' => TRUE的数组,该数组自动设置Form标签中的 enctype 然后我们添加一个表单域来获取文件。不使用Form::open()中的任何其他参数,表单将使用POST的默认方法和当前网址的动作。Form::file()是我们接受文件的输入字段。

由于我们的表单发布到同一个网址,我们需要创建一个接受POST输入的路径。$file变量将保存所有文件信息。

接下来,我们想用不同的名称保存文件,但首先我们需要获取上传文件的扩展名。所以我们使用guessExtension()方法,并将其存储在一个变量中。大多数使用文件的方法都可以在 Symfony 的文件库中找到。

最后,我们使用文件的move()方法将文件移动到其永久位置,第一个参数是我们将保存文件的目录;第二个是文件的新名称。

如果一切上传正确,我们显示'Success',如果不正确,我们显示'Error'

另见

  • 验证文件上传配方

验证文件上传

如果我们想允许用户通过我们的网络表单上传文件,我们可能想限制他们上传哪种文件。使用 Laravel 的Validator类,我们可以检查特定的文件类型,甚至将上传限制在一定的文件大小。

做好准备

对于这个食谱,我们需要一个标准 Laravel 安装,和一个示例文件来测试我们的上传。

怎么做...

按照以下步骤完成该配方:

  1. 在我们的routes.php文件中为表单创建一个路径:

    php Route::get('fileform', function() { return View::make('fileform'); });

  2. 创建表单视图:

    php <h1>File Upload</h1> <?php $messages = $errors->all('<p style="color:red">:message</p>') ?> <?php foreach ($messages as $msg) { echo $msg; } ?> <?= Form::open(array('files' => TRUE)) ?> <?= Form::label('myfile', 'My File (Word or Text doc)') ?> <br> <?= Form::file('myfile') ?> <br> <?= Form::submit('Send it!') ?> <?= Form::close() ?>

  3. 创建一条路线来验证和处理我们的文件:

    ```php Route::post('fileform', function() { $rules = array( 'myfile' => 'mimes:doc,docx,pdf,txt|max:1000' ); $validation = Validator::make(Input::all(), $rules);

    if ($validation->fails())
    {
    

    return Redirect::to('fileform')->withErrors($validation)->withInput(); } else { $file = Input::file('myfile'); if ($file->move('files', $file->getClientOriginalName())) { return "Success"; } else { return "Error"; } } }); ```

它是如何工作的...

我们从一个到达的路径开始保存我们的表单,然后查看表单的 html。在视图的顶部,如果我们在验证中得到任何错误,它们将在这里被重复。表单以Form::open (array('files' => TRUE))开始,将为我们设置默认动作、方法和enctype

接下来,我们创建一个路径来捕获帖子数据并验证它。我们将$rules变量设置为数组,首先检查特定的 mime 类型。我们想要多少就有多少。然后我们确保文件小于 1000 千字节,即 1 兆字节。

如果文件无效,我们将用户导航回包含错误消息的表单。如果 Laravel 检测到闪烁的错误信息,我们的视图中会自动创建$error变量。如果有效,我们会尝试将文件保存到服务器。如果保存正确,我们会看到"Success",如果不正确,我们会看到"Error"

还有更多...

文件的另一个常见验证是检查图像。为此,我们可以在我们的$rules数组中使用这个:

'myfile' => 'image'

这将检查以确保文件是.jpg.png.gif.bmp文件。

另见

  • 创建文件上传程序的配方

创建自定义错误消息

如果验证失败,Laravel 有内置的错误消息,但是我们可能希望定制这些消息,使我们的应用独一无二。本食谱展示了几种不同的方法来创建自定义错误消息。

做好准备

对于这个食谱,我们只需要一个标准安装的 Laravel。

怎么做...

要完成此配方,请遵循以下步骤:

  1. routes.php中创建一个路径来保存表单:

    php Route::get('myform', function() { return View::make('myform'); });

  2. 创建一个名为myform.php的视图,并添加一个表单:

    php <h1>User Info</h1> <?php $messages = $errors->all ('<p style="color:red">:message</p>') ?> <?php foreach ($messages as $msg) { echo $msg; } ?> <?= Form::open() ?> <?= Form::label('email', 'Email') ?> <?= Form::text('email', Input::old('email')) ?> <br> <?= Form::label('username', 'Username') ?> <?= Form::text('username', Input::old('username')) ?> <br> <?= Form::label('password', 'Password') ?> <?= Form::password('password') ?> <br> <?= Form::submit('Send it!') ?> <?= Form::close() ?>

  3. 创建一条路线处理我们的开机自检数据并验证:

    ```php Route::post('myform', array('before' => 'csrf', function() { $rules = array( 'email' => 'required|email|min:6', 'username' => 'required|min:6', 'password' => 'required' );

    $messages = array(
        'min' => 'Way too short! The :attribute must be atleast :min characters in length.',
        'username.required' => 'We really, really need aUsername.'
    );
    
    $validation = Validator::make(Input::all(), $rules,$messages);
    
    if ($validation->fails())
    {
        return Redirect::to('myform')->withErrors($validation)->withInput();
    }
    
    return Redirect::to('myresults')->withInput();
    

    })); ```

  4. 打开文件app/lang/en/validation.php,其中en为 app 默认语言。在我们的例子中,我们使用英语。在文件底部,更新attributes数组如下:

    php 'attributes' => array( 'password' => 'Super Secret Password (shhhh!)' ),

  5. 创建处理成功表单提交的路线:

    php Route::get('myresults', function() { return dd(Input::old()); });

它是如何工作的...

我们首先创建一个相当简单的表单,由于我们没有向Form::open()传递任何参数,它会将数据发布到同一个网址。然后我们创建一条路线来接受POST数据并验证它。作为最佳实践,我们还在我们的post路线之前添加了csrf过滤器。这将为跨站点请求提供一些额外的安全性。

我们在post路线中设置的第一个变量将保持我们的规则。如果有错误,下一个变量将保存我们想要使用的任何自定义消息。有几种不同的方法来设置消息。

要定制的第一条信息是min尺寸。在这种情况下,对于任何存在min规则的验证错误,它将显示相同的消息。显示错误时,我们可以使用:attribute:min保存表单字段名称和最小大小。

我们的第二条消息仅用于特定的表单字段和特定的验证规则。我们将表单字段名称放在第一位,然后是句点,然后是规则。这里,我们正在检查用户名是否是必需的,并设置错误消息。

我们的第三条消息设置在语言文件中进行验证。在attributes数组中,我们可以设置我们的任何表单字段名称来显示我们想要的任何自定义文本。此外,如果我们决定在整个应用中定制一个特定的错误消息,我们可以改变这个文件顶部的默认消息。

还有更多...

如果我们查看app/lang目录,我们会看到相当多的翻译已经是 Laravel 的一部分。如果我们的应用是本地化的,我们可以用我们选择的任何语言设置自定义验证错误消息。

另见

  • 创建一个简单的配方

在表格中加入蜜罐

网络的一个可悲现实是有“垃圾邮件机器人”,它们搜索网络并寻找提交垃圾邮件的表单。一种帮助对抗这种情况的方法是使用一种叫做蜜罐的技术。在这个食谱中,我们将创建一个自定义验证来检查垃圾邮件提交。

做好准备

对于这个食谱,我们只需要一个标准的 Laravel 安装。

怎么做...

要完成此配方,请遵循以下步骤:

  1. routes.php中创建一条路线来保持我们的形态:

    php Route::get('myform', function() { return View::make('myapp'); });

  2. 在名为myform.phpapp/view目录中创建一个视图,并添加表单:

    php <h1>User Info</h1> <?php $messages = $errors->all('<p style ="color:red">:message</p>') ?> <?php foreach ($messages as $msg) { echo $msg; } ?> <?= Form::open() ?> <?= Form::label('email', 'Email') ?> <?= Form::text('email', Input::old('email')) ?> <br> <?= Form::label('username', 'Username') ?> <?= Form::text('username', Input::old('username')) ?> <br> <?= Form::label('password', 'Password') ?> <?= Form::password('password') ?> <?= Form::text('no_email', '', array('style' =>'display:none')) ?> <br> <?= Form::submit('Send it!') ?> <?= Form::close() ?>

  3. 在我们的routes.php文件中创建一个路由来处理post数据,并验证它:

    ```php Route::post('myform', array('before' => 'csrf', function() { $rules = array( 'email' => 'required|email', 'password' => 'required', 'no_email' => 'honey_pot' ); $messages = array( 'honey_pot' => 'Nothing should be in this field.' ); $validation = Validator::make(Input::all(), $rules,$messages);

    if ($validation->fails())
    {
        return Redirect::to('myform')->withErrors($validation)->withInput();
    }
    
    return Redirect::to('myresults')->withInput();
    

    })); ```

  4. 在我们的routes.php文件中,创建一个自定义验证:

    php Validator::extend('honey_pot', function($attribute, $value,$parameters) { return $value == ''; });

  5. 创建一个用于成功页面的简单路线:

    php Route::get('myresults', function() { return dd(Input::old()); });

它是如何工作的...

我们首先创建一个相当简单的表单;因为我们没有向Form::open()传递任何参数,所以它会将数据发布到同一个网址。在表单中,我们创建了一个设计为空的字段,但是使用 CSS 对用户隐藏它。通过将它命名为带有单词email的东西,许多垃圾邮件机器人会将它误认为是一个email字段,并试图填充它。

然后,我们创建一条路线来接受post数据并对其进行验证,同时在路线之前添加一个csrf过滤器。我们向我们的no_email字段添加一个自定义验证规则,这将确保该字段保持为空。我们还为$messages数组中的规则创建了一条错误消息。

接下来,我们实际上在routes文件中创建我们的自定义验证规则。该规则将从表单字段中获取值,如果值为空,则返回TRUE

现在,如果一个机器人试图填写整个表单,它将不会生效,因为额外的字段被设计为保持空白。

还有更多...

创建自定义验证的一种替代方法是使用规则size: 0,这将确保honey_pot字段的长度正好是0字符。然而,这种方法使验证检查更加简单。

我们可能还想将任何蜜罐错误重定向到另一个没有表单的页面。这样,任何自动表单提交脚本都不会继续尝试提交表单。

使用编校器上传图像

有一些不同的 JavaScript 库可以将表单的文本区域变成所见即所得的编辑器。编校器是一个较新的库,但编码非常好,并在短时间内获得了相当多的流行。对于这个配方,我们将把编校器应用到我们的 Laravel 表单中,并创建允许通过编校器上传图像的路径。

做好准备

我们需要从https://github.com/dybskiy/redactor-js/tree/master/redactor下载一份版本的编校器。下载redactor.min.js保存到public/js目录。下载redactor.css并保存到public/css目录。

怎么做...

要完成这个配方,请按照的步骤操作:

  1. 在我们的routes.php文件中创建一个路径,用redactor字段保存我们的表单:

    php Route::get('redactor', function() { return View::make('redactor'); });

  2. 在我们的app/views目录中创建一个视图,并将其命名为redactor.php :

    php <!DOCTYPE html> <html> <head> <title>Laravel and Redactor</title> <meta charset="utf-8"> <link rel="stylesheet" href="css/redactor.css" /> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script src="js/redactor.min.js"></script> </head> <body> <?= Form::open() ?> <?= Form::label('mytext', 'My Text') ?> <br> <?= Form::textarea('mytext', '', array('id' =>'mytext')) ?> <br> <?= Form::submit('Send it!') ?> <?= Form::close() ?> <script type="text/javascript"> $(function() { $('#mytext').redactor({ imageUpload: 'redactorupload' }); }); </script> </body> </html>

  3. 制作一个处理图像上传的路线:

    ```php Route::post('redactorupload', function() { $rules = array( 'file' => 'image|max:10000' ); $validation = Validator::make(Input::all(), $rules); $file = Input::file('file'); if ($validation->fails()) { return FALSE; } else { if ($file->move('files', $file-> getClientOriginalName())) { return Response::json(array('filelink' => 'files/' . $file->getClientOriginalName())); } else { return FALSE; } } });

    ```

  4. 提交表单后,创建另一个路径来显示我们的表单输入:

    php Route::post('redactor', function() { return dd(Input::all()); });

它是如何工作的...

在创建我们的表单路径之后,我们创建视图来保存我们的表单 HTML。在页面的头部,我们加载了编校器 CSS、jquery 库(使用谷歌的 CDN)和编校器 JavaScript 文件。

我们的表单只有一个字段,一个名为mytext的文本区域。在我们的脚本区域,我们初始化文本区域字段上的密文,并将imageUpload参数设置为将接受图像上传的路线或控制器。我们的设置为redactorupload,因此我们为其创建了一条接受post数据的路线。

在我们的redactorupload路线中,我们进行一些验证,如果一切正常,图像将上传到我们的图像目录。为了让图像显示在我们的文本区域中,它需要一个 JSON 数组,该数组以文件链接为键,以图像路径为值。为此,我们将使用 Laravel 的内置Response::json方法,并传递一个带有图像位置的数组。

在我们的表单页面上,如果图像被正确验证和上传,编校器将在文本区域内显示图像。如果我们提交,我们将看到包含<img>标签和图像路径的文本。

还有更多...

虽然此方法专门用于图像上传,但非图像文件上传的工作方式非常相似。唯一真正的区别是文件上传路径也应该在 JSON 输出中返回文件名。

用 Jcrop 裁剪图像

图像编辑和操作有时在我们的应用中很难实现。使用 Laravel 和 Jcrop JavaScript 库,我们可以让任务变得更简单。

类型

下载示例代码

您可以从您在http://www.packtpub.com的账户中下载您购买的所有 Packt 书籍的示例代码文件。如果您在其他地方购买了这本书,您可以访问http://www.packtpub.com/support并注册,以便将文件直接通过电子邮件发送给您。

做好准备

我们需要从http://deepliquid.com/content/Jcrop_Download.html下载 Jcrop 库并解压。将文件jquery.Jcrop.min.js放入我们的public/js目录,将jquery.Jcrop.min.cssJcrop.gif文件放入我们的public/css目录。我们将使用谷歌 CDN 版本的 jQuery。我们还需要确保我们的服务器上安装了 GD 库,这样我们就可以进行图像处理。在我们的public目录中,我们需要一个图像文件夹来存储图像,并且应该为其设置可写的权限。

怎么做...

按照以下步骤完成此食谱:

  1. 让我们在routes.php文件中创建一个路径来保存我们的表单:

    php Route::get('imageform', function() { return View::make('imageform'); });

  2. app/views中创建上传图像的表单,文件名为imageform.php :

    php <h1>Laravel and Jcrop</h1> <?= Form::open(array('files' => true)) ?> <?= Form::label('image', 'My Image') ?> <br> <?= Form::file('image') ?> <br> <?= Form::submit('Upload!') ?> <?= Form::close() ?>

  3. 前往处理图像上传和验证:

    ```php Route::post('imageform', function() { $rules = array( 'image' => 'required|mimes:jpeg,jpg|max:10000' );

    $validation = Validator::make(Input::all(), $rules);
    
    if ($validation->fails())
    {
        return Redirect::to('imageform')->withErrors($validation);
    }
    else
    {
        $file = Input::file('image');
        $file_name = $file->getClientOriginalName();
        if ($file->move('images', $file_name))
        {
            return Redirect::to('jcrop')->with('image',$file_name);
        }
        else
        {
            return "Error uploading file";
        }
    }
    

    }); ```

  4. 为我们的 Jcrop 表单创建一条路线:

    php Route::get('jcrop', function() { return View::make('jcrop')->with('image', 'images/'. Session::get('image')); });

  5. 在我们的app/views目录中制作一个表单,我们可以在那里裁剪图像,文件名为jcrop.php :

    ```php

    Laravel and Jcrop

    Image Cropping with Laravel and Jcrop

    <img src="<?php echo $image ?>" id="cropimage">
        <?= Form::open() ?>
        <?= Form::hidden('image', $image) ?>
        <?= Form::hidden('x', '', array('id' => 'x')) ?>
        <?= Form::hidden('y', '', array('id' => 'y')) ?>
        <?= Form::hidden('w', '', array('id' => 'w')) ?>
        <?= Form::hidden('h', '', array('id' => 'h')) ?>
        <?= Form::submit('Crop it!') ?>
        <?= Form::close() ?>
    
        <script type="text/javascript">
            $(function() {
                $('#cropimage').Jcrop({
                    onSelect: updateCoords
                });
            });
            function updateCoords(c) {
                $('#x').val(c.x);
                $('#y').val(c.y);
                $('#w').val(c.w);
                $('#h').val(c.h);
            };
        </script>
    </body>
    

    ```

  6. 创建处理图像并显示的路线:

    ```php Route::post('jcrop', function() { $quality = 90;

    $src  = Input::get('image');
    $img  = imagecreatefromjpeg($src);
    $dest = ImageCreateTrueColor(Input::get('w'),
        Input::get('h'));
    
    imagecopyresampled($dest, $img, 0, 0, Input::get('x'),
        Input::get('y'), Input::get('w'), Input::get('h'),
        Input::get('w'), Input::get('h'));
    imagejpeg($dest, $src, $quality);
    
    return "<img src='" . $src . "'>";
    

    });

    ```

它是如何工作的...

我们先从一个基本文件上传开始;为了更简单,我们将只使用.jpg文件。我们使用验证来检查图像类型,并确保文件大小低于 10,000 千字节。文件上传后,我们将路径发送到我们的 Jcrop 路由。

在 Jcrop 路径的 HTML 中,我们创建了一个包含隐藏字段的表单,这些字段将保存裁剪的尺寸。JavaScript 函数updateCoords获取裁剪尺寸并更新那些隐藏字段的值。

当我们完成裁剪后,我们提交表单,我们的路线得到 POST 数据。图像在 GD 库中运行,并根据发布的尺寸进行裁剪。然后我们覆盖图像并显示更新和裁剪的文件。

还有更多...

虽然这个食谱只包括裁剪一个 jpg 图像,但是添加gifpng图像并不是很困难。我们只需要通过使用File::extension()将文件名传递给 Laravel 来获得文件扩展名。然后,我们可以做一个switch或者if语句来使用适当的 PHP 函数。例如,如果分机是.png,我们会使用imagecreatefrompng()imagepng()。更多信息可在http://www.php.net/manual/en/ref.image.php找到。

创建自动完成文本输入

在我们的 web 表单上,有时我们可能希望有一个自动完成文本字段。这对于填充常用搜索词或产品名称非常方便。使用 jQueryUI 自动完成库和 Laravel,这变成了一个简单的任务。

做好准备

在这个食谱中,我们将使用 jQuery 和 jQueryUI 的 CDN 版本;然而,如果我们想在本地拥有它们,我们也可以下载它们并将它们放在我们的public/js目录中。

怎么做...

要完成此配方,请遵循以下步骤:

  1. 创建一个路径来保存我们的自动完成表单:

    php Route::get('autocomplete', function() { return View::make('autocomplete'); });

  2. 用我们表单的 HTML 和 JavaScript 在名为autocomplete.phpapp/views目录中创建一个视图:

    ```php <!DOCTYPE html>

    Laravel Autocomplete

    Laravel Autocomplete

        <?= Form::open() ?>
        <?= Form::label('auto', 'Find a color: ') ?>
        <?= Form::text('auto', '', array('id' => 'auto'))?>
        <br>
        <?= Form::label('response', 'Our color key: ') ?>
        <?= Form::text('response', '', array('id' =>'response', 'disabled' => 'disabled')) ?>
        <?= Form::close() ?>
    
        <script type="text/javascript">
            $(function() {
                $("#auto").autocomplete({
                    source: "getdata",
                    minLength: 1,
                    select: function( event, ui ) {
                        $('#response').val(ui.item.id);
                    }
                });
            });
        </script>
    </body>
    

    ```

  3. 创建一条路线,该路线将填充autocomplete字段的数据:

    ```php Route::get('getdata', function() { $term = Str::lower(Input::get('term')); $data = array( 'R' => 'Red', 'O' => 'Orange', 'Y' => 'Yellow', 'G' => 'Green', 'B' => 'Blue', 'I' => 'Indigo', 'V' => 'Violet', ); $return_array = array();

    foreach ($data as $k => $v) {
        if (strpos(Str::lower($v), $term) !== FALSE) {
            $return_array[] = array('value' => $v, 'id' =>$k);
        }
    }
    return Response::json($return_array);
    

    }); ```

它是如何工作的...

在我们的表单中,我们正在创建一个文本字段来接受将用于autocomplete的用户输入。还有一个禁用的文本字段,我们可以使用它来查看所选值的标识。如果您有一个特定数值的标识,或者不是以标准方式命名的标识,这将非常有用。在我们的例子中,我们使用颜色的第一个字母作为标识。

当用户开始键入时,autocomplete使用查询字符串中的单词term向我们添加的源发送GET请求。为了处理这个问题,我们创建了一个获取输入的路由,并将其转换为小写。对于我们的数据,我们使用了一个简单的值数组,但是在这一点上添加数据库查询是相当容易的。我们的路由检查数组中的值,看是否与用户输入匹配,如果匹配,则将标识和值添加到我们将返回的数组中。然后,我们将数组输出为 JSON,用于autocomplete脚本。

回到我们的表单页面,当用户选择一个值时,我们将 ID 添加到禁用的响应字段中。很多时候,这将是一个隐藏的字段,我们可以在提交表单时传递它。

还有更多...

如果我们希望我们的getdata路由只能从我们的自动完成表单或其他一些 AJAX 请求中访问,我们可以简单地将代码包装在if (Request::ajax()) {}中,或者创建一个拒绝任何非 AJAX 请求的过滤器。

制作验证码风格的垃圾邮件捕捉器

打击自动填写网页表单的“机器人”的一种方法是使用验证码技术。这个给用户展示了一个带有一些随机字母的图像;用户必须用这些字母填写文本字段。在这个食谱中,我们将创建一个验证码图像,并验证用户是否正确输入了它。

做好准备

我们需要一个标准的 Laravel 安装,并确保我们的服务器上安装了 GD2 库,这样我们就可以创建一个映像。

怎么做...

要完成此配方,请遵循以下步骤:

  1. 在我们的app目录中,创建一个名为libraries的目录,在我们的composer.json文件中,更新如下:

    php "autoload": { "classmap": [ "app/commands", "app/controllers", "app/models", "app/database/migrations", "app/database/seeds", "app/tests/TestCase.php", "app/libraries" ] },

  2. 在我们的app/libraries目录中,创建一个名为Captcha.php的文件来保存我们简单的Captcha类:

    ```php <?php class Captcha { public function make() { $string = Str::random(6, 'alpha'); Session::put('my_captcha', $string);

        $width      = 100;
        $height     = 25;
        $image      = imagecreatetruecolor($width,$height);
        $text_color = imagecolorallocate($image, 130, 130,130);
        $bg_color   = imagecolorallocate($image, 190, 190,190);
    
        imagefilledrectangle($image, 0, 0, $width, $height,$bg_color);        
        imagestring($image, 5, 16, 4, $string,$text_color);
    
        ob_start();
        imagejpeg($image);
        $jpg = ob_get_clean();
        return "data:image/jpeg;base64,". base64_encode($jpg);
    }
    

    } ```

  3. 在我们应用的根目录下,打开命令行界面更新composer自动加载器:

    ```php php composer.phar dump-autoload

    ```

  4. routes.php中创建一条路线,用captcha :

    php Route::get('captcha', function() { $captcha = new Captcha; $cap = $captcha->make(); return View::make('captcha')->with('cap', $cap); });

    保存表单 5. 在名为captcha.php :

    php <h1>Laravel Captcha</h1> <?php if (Session::get('captcha_result')) { echo '<h2>' . Session::get('captcha_result') . '</h2>'; } ?> <?php echo Form::open() ?> <?php echo Form::label('captcha', 'Type these letters:') ?> <br> <img src="<?php echo $cap ?>"> <br> <?php echo Form::text('captcha') ?> <br> <?php echo Form::submit('Verify!') ?> <?php echo Form::close() ?>

    app/views目录中创建我们的captcha 视图 6. 创建路线来比较captcha值和用户输入:

    php Route::post('captcha', function() { if (Session::get('my_captcha') !==Input::get('captcha')) { Session::flash('captcha_result', 'No Match.'); } else { Session::flash('captcha_result', 'They Match!'); } return Redirect::to('captcha'); });

它是如何工作的...

我们首先更新我们的composer.json文件,将我们的libraries目录添加到自动加载器中。现在,我们可以将任何我们想要的类或库添加到该目录中,即使它们是定制类或者可能是一些遗留代码。

为了保持简单,我们用单一的make()方法创建了一个简单的Captcha类。在这个方法中,我们首先使用拉威尔的Str:random()创建一个随机字符串,我们告诉它输出一个只有字母的 6 个字符的字符串。然后,我们将该字符串保存到一个会话中,以便以后可以使用它进行验证。

使用该字符串,我们创建一个 100x25 像素的 jpg 图像,具有灰色背景和较深的灰色文本。我们不是将文件保存到服务器,而是使用输出缓冲区并将图像数据保存到一个变量中。这样,我们可以创建一个数据 URI 发送回我们的路线。

接下来,我们需要运行 composer 的dump-autoload命令,这样我们的新类就可以被应用使用了。

在我们的captcha路线中,我们使用Captcha类创建captcha数据 URI,并将其发送到我们的表单。出于我们的目的,表单将简单地显示图像,并要求在文本字段中输入字符。

当用户提交表单时,我们将Captcha类创建的会话与用户输入进行比较。在这个配方中,我们只是检查这两个值是否匹配,但是我们也可以创建一个自定义的验证方法,并将其添加到我们的规则中。然后,我们设置一个会话,说明它是否匹配,并将用户返回验证码页面。