前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Laravel5.2之Demo1——URL生成和存储

Laravel5.2之Demo1——URL生成和存储

作者头像
botkenni
发布2022-01-10 09:13:45
24.1K0
发布2022-01-10 09:13:45
举报
文章被收录于专栏:IT码农

引言:

本文基于Laravel框架做的一个URL生成和存储demo,主要目的是学习使用Laravel框架。内容基于英文书籍《Packt.Laravel.Application.Development.Blueprints》第一章节,似乎没有中文版。书籍基于Laravel4的,学习时使用Laravel5.2框架开发。

学习主题

该demo主要涉及如下几个知识点:

  1. 创建数据库并迁移数据表
  2. 创建表单,学习Laravelblade模板引擎
  3. 创建名为Link的模型Model
  4. 保存数据进入数据库
  5. 从数据库中获得URL链接并重定向

1、创建数据库并迁移数据表单

表迁移(Migrations)其实就是数据库(Database)的版本控制,允许团队修改数据库架构,并保存当前数据库最新架构信息,为了创建并迁移创建的URL数据库,需要做几个步骤:

(1)、首先创建一个数据库并定义该数据库与Laravel的连接信息,Laravel框架为数据库连接提供了配置文件:/config/database.phpLaravel支持SQlite、MySQL、PostgreSQL、SQLSRV数据库,本教程使用MySQL数据库。

(2)、创建一个名为urls的数据库,终端登入mysql服务器或者使用phpMyAdmin敲入SQL语句:CREATE DATABASE urls。可以使用PHPStorm这个IDE的database模块远程创建urls数据库。

(3)、在成功创建数据库urls后,开始配置数据库名称和用户名密码,在/config/database.php里配置host,database,username,password,由于配置文件使用env()函数先读取.env文件里的值,所以可以直接在.env文件里配置。.env文件可以从.env.example文件复制得来,如修改.env文件中值:DB_HOST=localhost,DB_DATABASE=urls,DB_USERNAME=root,DB_PASSWORD=laravel;也可以修改/config/database.php文件为:'host'=>'localhost','database'=> 'urls','username'=>'root','password' =>'laravel'。数据库用户名为安装MySQL时配置的。

(4)、使用LaravelArtisan CLI工具命令创建migrations迁移文件,可以在终端进入项目根目录输入php artisan命令查看Artisan命令列表。现在创建一个名为links的迁移文件:php artisan make:migration create_links_table --create=links,会在/database/migrations/文件夹下新建一个date+create_links_table.php文件,该文件源码主要包含两个非常重要的方法:up()/down()。当执行数据表迁移命令php artisan migrate时执行的是up()方法;当执行回滚上一次迁移命令php artisan migrate:rollback时执行的是down()方法,该命令具有破坏性会删除links数据表。曾经遇到一个场景:需要给数据表test增加一个字段age但又要保留test表里数据,可以再创建一个迁移文件php artisan make:migration create_links_table --table=links,生成的迁移文件中up()方法里引用了Schema::table()方法而不是Schema::create()方法,再添加$table->string('age')->default(0);语句,删除原来的'id'和timestamps邮戳语句,再执行php artisan migrate迁移命令。

(5)、在创建的迁移文件内增加两个字段:table->text('url');

注明:可以安装phpstorm这个IDE,使用它的database模块查看数据库,说实话个人用的感觉还挺顺手的,当然也可以安装navicat premium软件查看。

2、创建Form表单

(1)、在resources/views/文件夹下创建一个urls文件夹,在urls文件夹下创建一个form.blade.php文件文件名需要有blade字符串,laravel会自动识别这个文件为blade模板文件。form模板代码为:

代码语言:javascript
复制
    <html lang="en">
    <head>
        <title>URL Shortener</title>
        <link rel="stylesheet" href="{{asset('css/urls/style.css')}}">
    </head>
        <body>
            <div id="container">
                <h2>短链接生成器</h2>
                {{Form::open(array('url'=>'/url','method'=>'post'))}}
                {{Form::text('link', '请输入您的网址!')}}
                {{--{{Form::text('link',Input::old('link'), array('placeholder'=>'请输入您的网址!'))}}--}}
                {{Form::close()}}
            </div>
        </body>
    </html>

注明:我的Laravel代码会报错没有Input这个类,很奇怪,那就把这一句注销掉吧。如果你知道咋解决,请在评论留言给我,谢谢。样式style.css文件可以用asset()函数在public文件夹下找到路径,在这里就是public/css/urls/style.css。当然,也可以不用这个Form类,直接写<form></form>表单html代码也行。这里的url表示提交表单时的路由,方法为post。在这里使用laravelcollective/html这个组件,顺便了解下怎么在laravel中安装组件。 这里书中使用了laravel4.*自带的Form类,但laravel5.*已经移除了,可以通过composerComposer官网安装。可以进入官网https://laravelcollective.com/docs/5.1/html找安装和配置方式,也可以去packagist.org中找https://packagist.org/packages/laravelcollective/html,这里推荐一个非常好用的网站packagist,PHP中所有组件components都可以在这里找到并通过composer安装。《Modern PHP》(可以去pan.java1234.com搜到英文版的)这本书中倡导PHP软件开发应该使用组件components方式来做,利用别人的轮子会加速开发效率,组件components可装可卸,组件式代码比面条式代码读起来更舒服!!! 通过composer安装也很简单,就是在项目根目录下的composer.json文件'require'数组中添加"laravelcollective/html": "5.2.*",,再composer update就行,安装完laravelcollective/html后在config/app.php文件中配置这个组件的服务serviceprovider,在'providers'数组中加上Collective\Html\HtmlServiceProvider::class,,在'aliases'数组中加上'Form' => Collective\Html\FormFacade::class,'Html' => Collective\Html\HtmlFacade::class,,就可以用这个组件轮子了,实际上很多组件也都是这么安装配置的。 样式style.css代码为:

代码语言:javascript
复制
    div#container{padding-top:100px;text-align:center;width:75%;margin:auto;border-radius:4px}
    div#container h2{font-family:Arial,sans-serif;font-size:28px;color:#555}
    div#container h3{font-family:Arial,sans-serif;font-size:28px}
    div#container h3.error{color:#a00}
    div#container h3.success{color:#0a0}
    div#container input{display:block;width:90%;float:left;font-size:24px;border-radius:5px}
    div#error,div#success{border-radius:3px;display:block;width:90%;padding:10px}
    div#error{background:#ff8080;border:1px solid red}
    div#success{background:#80ff80;border:1px solid #0f0}

balde模板页面写完,然后在routes.php路由文件中写个路由:

代码语言:javascript
复制
Route::get('/url', function(){
    return view('urls.form');//urls为创建的文件夹
});

这里路由第二个参数为匿名函数,直接返回视图,当然可以建个控制器php artisan make:controller UrlController,在控制器里写个getUrl()方法返回视图,那路由就要这么写了:Route::get('url', 'UrlController@getUrl')。 最后输入URL:http://yourhost/url,则blade模板页面如图所示:

3、创建名为Link的Model

Laravel提供了一个非常好用的ORM(Object Relationship Mapping)为Eloquent ORM,其实就是Model层,来管理数据库中的数据表且一一对应关系。Eloquent比较好用在于它提供了很多Feature功能模块,这些模块提供了许多面向对象的方法便于使用,这样就不用写SQL语句了,且代码看起来也很舒服。。不过有时也推荐使用它的Query Builder查询构造器,实际上就是SQL语句封装的类,性能会比较高一些,个人遇到过一个场景:使用Eloquent ORM性能有点慢,导致PHP执行过长报503 Time Out,改成Query Builder后性能高很多脚本执行很快搞定,当然各有利弊,毕竟Eloquent很强大很好用。 在项目根目录执行Artisan命令php artisan make:model Link后,生成app/Link.php文件,这个model通过配置用来管理MySQL中的links数据表,在Link这个model里写上配置:

代码语言:javascript
复制
    class Link extends Model
    {
        //
        protected $table = 'links';
        protected $fillable = ['url', 'hash'];
    }

table变量配置成MySQL中links数据表的名称,fillable用来配置数据表字段(column)被批量创建和更新的,因为后文在保存数据进入表里时使用Link::create([])方法来进行批量赋值的。可以查看Model这个class源码里有table和fillable字段,这个Model类提供了许多好用的方法,有时间可以瞅瞅。如果不需要laravel自动创建的时间可以写上public timestamps = false;再执行迁移命令,links数据表里就没有'created_at'/'updated_at'字段了。这里注意下:如果不写table变量,laravel会自动根据model名字复数来找数据表,如这个model名字是link,那就找links表。

4、保存数据进入数据库

写好视图表单后,再就是写表单的提交路由及其控制器逻辑,在控制器中引用创建好的Link这个Model往links数据表里存数据。原文书中是直接在路由中匿名函数里写数据存储逻辑,这里个人还是先创建一个控制器php artisan make:controller UrlController,在控制器里写数据存储逻辑比较好。实际上,控制器也就是路由层route、视图层view与模型model层的黏合剂而已,一般写laravel代码流程也仅此而已:现在路由里写好路由,再建立好model(包括创建好migrations和model,写好数据库连接配置、model配置、执行migrations表迁移),再在控制器controller里写好业务逻辑,返回response如blade视图view或直接一个"hello world"字符串吧,最后要是返回view那就在resources/views里写个view就行。laravel框架使用也仅此而已,没有那么复杂,对于我们这样的刚刚入门,了解这个流程就可以玩一玩了!!!

(1)、验证输入 在提交表单时都要验证输入数据是否符合规定,免得让脏数据进入数据表里,laravel提供了Validation模块来做表单验证并且可以在视图中显示验证错误信息,具体想了解下的可以看我这篇文章:Laravel学习笔记之Validator。

在验证表单时首先需要写验证规则$rules,本demo仅有一个输入且输入要符合URL格式,那就要考虑两个问题:怎么得到表单的输入$input和怎么写符合URL的$rules验证规则。首先使用验证方法Validator::make([], []),这个方法的第一个参数是取得的表单输入$input,第二个参数是验证规则$rules。demo中只有一个输入可以使用Input::all()取得或者Input::get('link'),其中link为这个输入的name,对应表单视图的{{Form::text('link', '请输入您的网址!')}}这个link,$rules验证规则这么写:

代码语言:javascript
复制
    $rules = array(
           'link' => 'required|url'
         );

这里'required'是输入不能为空,是laravel自带的验证规则,'url'也是laravel自带的URL验证规则,就是格式得符合URL格式,'|'表示且的意思。 好,现在就按照流程写代码: 首先:

代码语言:javascript
复制
    Route::post('url', 'UrlController@postUrl');

然后在UrlController中写上:

代码语言:javascript
复制
public function postUrl(){
    $rules = array(
       'link' => 'required|url'
     );
    //$validation = Validator::make(Input::all(),$rules);
    $validation = Validator::make(Input::get('link'),$rules);
}

这里这个存储变量validation存储了很多验证信息,很有用,如验证通过(validation->passes())和验证失败(validation->fails()),这两个函数返回Boolean结果,还有

代码语言:javascript
复制
    public function getUrl(){
        $title = 'Url Generator';
        return view('urls.form')->with('titletitle', $title);//blade模板中直接使用$titletitle变量就行,如<title>{{$titletitle}}</title>
    }
    public function postUrl(){
        $title = 'Url Generator';
        return Redirect::to('/url')->with('titletitle', $title);//这里重定向页面,在blade模板视图中得到$titletitle变量可以这么做,Session::get('titletitle'),检查有无变量这么做Session::has('titletitle')
    }

然后在postUrl()方法中写上验证失败的话重定向URL表单提交页面:

代码语言:javascript
复制
    if($validation->fails()) {
         return Redirect::to('/url')
         ->withInput()
         ->withErrors($validation);
    }

这里errors变量在blade视图模板中可以直接引用就不用Session::get()了,这是因为laravel会自动把这个变量和视图模板绑定,这errors是个特殊的变量,在form.blade.php视图中添加上验证错误信息代码。withInput()函数会在返回表单时在input里填上刚刚输入的旧数据。

(2)、将验证信息传到模板视图中

代码语言:javascript
复制
    @if(Session::has('errors'))
       <h3 class="error">{{$errors->first('link')}}</h3>
    @endif

first()函数返回link表单的第一个验证错误信息。当然也可以遍历验证信息并显示出来:

代码语言:javascript
复制
    @if(Session::has('errors'))
            <div class="alert alert-danger">
                <ul>
                    @foreach($errors->all() as $error)
                        <li>{{$error}}</li>
                    @endforeach
                </ul>
            </div>
    @endif

5、深度优化控制器并处理表单Form

代码的else部分主要处理当验证通过后,主要实现以下逻辑:

  • 检查link链接是否已经在数据表里
  • 如果link链接已经在数据表里,返回该短连接
  • 如果link链接不在数据表里,那就为该链接创建一个hash字段
  • 根据提供数据在数据表里插入一个记录record
  • 返回该链接给用户(1).使用Query Builder的where()方法,并传入Input::get('link')参数验证数据表里是否已经有该链接,并链式使用first()方法取出第一个结果:
代码语言:javascript
复制
    $link = Link::where('url','=',Input::get('link'))->first();

(2).如果数据表里有该链接,重定向到表单页面并带上数据表的hash字段:

代码语言:javascript
复制
    if($link) {
        return Redirect::to('/url')->withInput()->with('link',$link->hash);
    }

可以通过$link->columnName取得数据表里的字段值。这里with('name','value')等同于驼峰方法withName('value')方法,上文也说明了。在form.blade视图中也加上消息:

代码语言:javascript
复制
@if(Session::has('link'))
   <h3 class="success">
     {{Html::link(Session::get('link'),'Click here for your shortened URL')}}//Html类是laravelcollective/html这个模块里的类,或者直接写个`a`超链接标签也行
   </h3> @endif

(3).链接不在数据表里,为该链接创建一个hash字段,原文使用newHash = Str::random(6)创建一个包含数字字母的字符长度为6的字符串,再去表里验证该newHash是唯一的,这样比较麻烦,可以直接使用Hash::make(

代码语言:javascript
复制
else{
    $newHash = Hash::make(Input::get('link'));//根据输入的link做hash哈希就行或者别的更简短的输入值
}

(4).向link数据表里插入一个新的记录record:

代码语言:javascript
复制
else{
    $newHash = Hash::make(Input::get('link'));//根据输入的link做hash哈希就行或者别的更简短的输入值
    Link::create([
        'url' => Input::get('link'),
        'hash' => $newHash
        ]);
}

使用Link模型的create()方法创建一条record,或者:

代码语言:javascript
复制
    $link = new Link();
    $link->url = Input::get('link');
    $link->hash = $newHash;
    $link->save();

之前研究过一个小点:使用create方式是需要在Link模型类中写上$fillable指定批量赋值字段,否则报错,而这个save方式不需要这么做。

(5).再重定向到表单提交页面

代码语言:javascript
复制
    return Redirect::to('/url')
           ->withInput()
           ->with('link', $newHash);

这里带上$newHash变量是为了后面捕获这个变量后,根据这个变量从数据表里查找对应的url值。

6、从数据库中取出URL并且重定向

最后根据生成的URL获取其hash部分,根据hash值从links数据表取出对应的URL为了重定向,这里英文原文也是在路由中写逻辑,这里也在路由里写逻辑:

代码语言:javascript
复制
Route::get('/url/{hash}', function($hash){
    $link = Link::where('hash',$hash)->first();
    if($link){
        return Redirect::to($link->url);
    }else{
        return Redirect::to('/url')->with('message', 'Invalid Link');
    }
})->where('hash', '[0-9a-zA-Z+]');

{hash}是一个路由参数,作为匿名函数的参数,并且正则限制其是由数字字母组合where('hash', '[0-9a-zA-Z+]'),如果links数据表里有数据就跳转到这个链接去,没有则返回message给blade模板视图,所以form.blade模板视图需要添加显示:

代码语言:javascript
复制
    @if(Session::has('message'))
        <h3 class="error">{{Session::get('message')}}</h3>
    @endif
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016/10/10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言:
  • 学习主题
  • 1、创建数据库并迁移数据表单
  • 2、创建Form表单
  • 3、创建名为Link的Model
  • 4、保存数据进入数据库
  • 5、深度优化控制器并处理表单Form
  • 6、从数据库中取出URL并且重定向
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档