PHP_Laravel

简介

Laravel是一套简介,优雅PHP Web开发框架(PHP Web Framework), 通过简单,高雅,表达式语法开发Web应用。

特点:

  1. 语言优美

  2. 用户体验好

Composer

使用Composer安装Laravel

Composer中文镜像

  • 修改composer的全局配置文件

> composer config -g repo.packagist composer https://packagist.phpcomposer.com
  • 创建一个Laravel项目

> composer create-project laravel/laravel --prefer-dist
> composer create-project laravel/laravel blog --prefer-dist

--prefer-dist 下载压缩版本.
blog别名

初始化配置

  1. PHP版本>=5.5.9

  2. 开启rewrite和vhost

    httpd.conf  // 配置虚拟目录
  3. 开启PHP扩展

extension=php_openssl.dll
extension=php_mbstring.dll
extension=php_pdo_mysql.dll

配置伪静态.htaccess, 和 入口文件放在同级目录

Laravel参考文档5.1
Laravel参考文档5.2

Laravel目录结构

Laravel目录结构

目录或文件说明
app包含Controller、Model、路由等在内的应用目录,大部分业务将在该目录下进行
– Events事件目录
– Exceptions包含了自定义错误和异常处理类
– HttpHTTP传输层相关的类目录
– – Controllers控制器目录
– – Middleware中间件目录
– – Requests请求类目录
– – Kernel.php包含http中间件和路由中间件的内核文件
– – routes.php强大的路由
– Jobs该目录下包含队列的任务类
– Listeners监听器目录
– Providers服务提供者目录
– User.php自带的模型实例,新建的Model默认也存储在该目录
bootstrap框架启动载入目录
– cache存放框架启动缓存,web服务器需要有该目录的写入权限
config各种配置文件的目录
- app.php系统级配置文件
– auth.php用户身份认证配置文件,指定好table和model可以很方便地用身份认证功能
– broadcasting.php事件广播配置文件
– cache.php缓存配置文件
– compile.php编译额外文件和类需要的配置文件,一般用户很少用到
– database.php数据库配置文件
– filesystems.php文件系统配置文件,这里可以配置云存储参数
– mail.php电子邮件配置文件
– queue.php消息队列配置文件
– services.php可存放第三方服务的配置信息
– session.php配置session的存储方式、生命周期等信息
– view.php模板文件配置文件,包含模板目录和编译目录等
database数据库相关目录
public网站入口,应当将ip或域名指向该目录而不是根目录。可供外部访问的css、js和图片等资源皆放置于此目录
- .htaccessApache服务器用该文件重写URL
– web.configIIS服务器用该文件重写URL
resources资源文件目录
– assets可存放包含LESS、SASS、CoffeeScript在内的原始资源文件
– lang本地化文件目录
– views视图文件
storage存储目录。web服务器需要有该目录及所有子目录的写入权限
– app可用于存储应用程序所需的一些文件
– framework该目录下包括缓存、sessions和编译后的视图文件
– logs日志目录
tests测试目录
vendor该目录下包含Laravel源代码和第三方依赖包
.env环境配置文件。config目录下的配置文件会使用该文件里面的参数,不同生产环境使用不同的.env文件即可
artisan强大的命令行接口,可以在app/Console/Commands下编写自定义命令
composer.json存放依赖关系的文件
composer.lock锁文件,存放安装时依赖包的真实版本
gulpfile.jsgulp 配置文件
package.json
phpspec.ymlphpspec(一种PHP测试框架)配置文件
phpunit.xmlphpunit(一种PHP测试框架)配置文件
server.phpPHP内置的Web服务器将把这个文件作为入口。以public/index.php为入口的可以忽略掉该文件

composer.json配置

{    
    "name": "laravel/laravel",    //项目名称
    "description": "The Laravel Framework.",    //描述
    "keywords": ["framework", "laravel"],    //关键词
    "license": "MIT",    //许可协议
    "type": "project",    //类型
    "require": {    
        "php": ">=5.5.9",    //PHP版本
        "laravel/framework": "5.2.*"    //框架版本
    },    
    "require-dev": {    //依赖包
        "fzaninotto/faker": "~1.4",    
        "mockery/mockery": "0.9.*",    
        "phpunit/phpunit": "~4.0",    
        "symfony/css-selector": "2.8.*|3.0.*",    
        "symfony/dom-crawler": "2.8.*|3.0.*"    
    },    
    "autoload": {    //自动加载
        "classmap": [    
            "database"    
        ],    
        "psr-4": {    //一种自动加载的规范
            "App\\": "app/"    
        }    
    },    
    "autoload-dev": {    //加载测试
        "classmap": [    
            "tests/TestCase.php"    
        ]    
    },    
    "scripts": {    //执行脚本
        "post-root-package-install": [    
            "php -r \"copy('.env.example', '.env');\""    
        ],    
        "post-create-project-cmd": [    
            "php artisan key:generate"    
        ],    
        "post-install-cmd": [    
            "php artisan clear-compiled",    
            "php artisan optimize"    
        ],    
        "post-update-cmd": [    
            "php artisan clear-compiled",    
            "php artisan optimize"    
        ]    
    },    
    "config": {    //配置项
        "preferred-install": "dist"    //优先安装压缩版
    },    
    "repositories": {    //配置composer镜像
        "packagist": {    
            "type": "composer",    
            "url": "https://packagist.phpcomposer.com"    
        }    
    }    
}    

HTTP

基础路由

clipboard.png

基础路由

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
Route::match(['get', 'post'], '/test', $callback); // 匹配各种HTTP请求
Route::any('foo', $callback); // 任何请求匹配

字体:

<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css">

controller

Route::controller('index', 'IndexController');

class IndexController extends Controller {
    public function getIndex() {
        return 'Index'; 
    }
}

路由参数

必选参数

一个参数和多个参数的情况
语法:{字段}

Route::get('user/{id}', function($id) {
    echo $id;
});

Route::get('user/{id}/age/{num}', function($id, $num) {
    echo 'id: ' . $id . ' num: ' . $num;
});

可选参数

语法:

  1. {字段?}

  2. 匿名函数参数定义初值

Route::get('user/{name?}', function ($name = null) {
    echo $name;
});

多个参数下,最后一个参数可以可选。

参数约束

正则约束: 主要做类型限制.
语法:
增加where()方法条件.

Route::get('user/{name}', function ($name) {
    //
})->where('name', '[A-Za-z]+');

Route::get('user/{id}', function ($id) {
    //
})->where('id', '[0-9]+');

Route::get('user/{id}/{name}', function ($id, $name) {
    //
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

高级路由

http普通路由(获取路由地址)
调用:route(profile)

Route::get('user1', ['as' => 'profile', function() {
    var_dump(route('profile')); // 路由地址  // http://www.lara.com/user1
}]);

http控制器路由(在控制器中获取路由地址)

Route::get('user', [
    'as' => 'profile', 'uses' => 'UserController@index'
]); 

路由分组

把类似功能的路由分组,便于管理维护。

// Route::get('admin/login', 'Admin\IndexController@login');
// Route::get('admin/index', 'Admin\IndexController@index');

// 提取 分组admin 和命名空间 
Route::group(['prefix' => 'admin', 'namespace' => 'Admin'], function () {
    Route::get('login', 'IndexController@login');
        Route::get('index', 'IndexController@index');
});

控制器

基础控制器

固定模板
需要命名空间,
命名空间作用:告知自动加载机制,怎样索引到当前目录文件.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;

class UserController extends Controller {
    //
}

创建控制器:

<?php

    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use App\Http\Requests;    
    
    class IndexController extends Controller {
        public function index() {
            echo 'index';            
        }
    }

?>

所有的控制器方法,都需要在路由中做配置.

Route::get('controller', 'IndexController@index');  // 控制器文件名@控制器方法名

使用Artisan方式创建控制器:

> php artisan make:controller UserController 

使用Artisan查看路由列表:

> php artisan route:list

RESTful 资源控制器

一次性可以配置一堆相同类似的路由。
语法:Route::resource('article', 'ArticleController@index');

$ php artisan route:list
+--------+-----------+------------------------------+-----------------------+------------------------------------------------------------+------------+
| Domain | Method    | URI                          | Name                  |Action                                                      | Middleware |
+--------+-----------+------------------------------+-----------------------+-----------------------------------------------------------+------------+
|        | GET|HEAD  | /                            |                       | Closure                                                    |            |
|        | POST      | admin/article                | admin.article.store   | App\Http\Controllers\Admin\ArticleController@index@store   |            |
|        | GET|HEAD  | admin/article                | admin.article.index   | App\Http\Controllers\Admin\ArticleController@index@index   |            |
|        | GET|HEAD  | admin/article/create         | admin.article.create  | App\Http\Controllers\Admin\ArticleController@index@create  |            |
|        | DELETE    | admin/article/{article}      | admin.article.destroy | App\Http\Controllers\Admin\ArticleController@index@destroy |            |
|        | PUT|PATCH | admin/article/{article}      | admin.article.update  | App\Http\Controllers\Admin\ArticleController@index@update  |            |
|        | GET|HEAD  | admin/article/{article}      | admin.article.show    | App\Http\Controllers\Admin\ArticleController@index@show    |            |
|        | GET|HEAD  | admin/article/{article}/edit | admin.article.edit    | App\Http\Controllers\Admin\ArticleController@index@edit    |            |
+--------+-----------+------------------------------+-----------------------+-----------------------------------------------------------+------------+

中间件

中间件的理解:在路由上层加了一层保护过滤

web中间件

web中间件模板:

Route::group(['middleware' => ['web']], function () {
    //
});

使用web中间件,才能使用Session服务和Csrf服务的保护

Route::group(['middleware' => 'web'], function() {
        Route::get('/', function () {
                session(['key' => 11]);
            return view('welcome');
        });
        
        Route::get('test', function() {
            var_dump(session('key'));
            return 'test';
        });
});

自定义中间件

Kernel.php文件中修改 $routeMiddleware 配置

protected $routeMiddleware = [
  'auth' => \App\Http\Middleware\Authenticate::class,
  'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
  'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
  'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
  'admin.login' => \App\Http\Middleware\AdminLogin::class // 增加自定义中间件
];

使用自定义中间件

Route::group(['middleware' => 'admin.login'], function () {
});

artisan 方式创建中间件

> php artisan make:middleware AdminLogin

CSRF必须要使用中间件调用.

视图

视图:处理结果的可视化

渲染视图:
语法:view(视图路径)

public function login() {
    return view('admin/login');
}

数据传递:

  1. with

  2. 传参

  3. compact

with()

传入:

public function login() {
    $name = 'NAME';
    return view('admin\color')->with('name', $name);
}

public function login() {
    $data = [
        'name' => 'NAME',
        'age' => 24
    ];
    return view('admin\color')->with('data', $data);
}

显示:

<div class="title"><?php echo $data['name'] ?></div>
<div class="title"><?php echo $data['age'] ?></div>

传参

return view('admin\color', ['name' => 'NAME']);

return view('admin\color', $data);

compact()

return view('admin\color', compact('title'));

Blade

基础用法

显示变量

<div class="title">{{$title}}</div>

屏蔽{{}}
语法:@{{字段}}

<div class="title">@{{$title}}</div>

解析HTML标签

<div class="title">{!!$title!!}</div>

流程控制

if

使用@if,@elseif, @else , @endif

<div class="title">
    @if ($data['age'] > 20)
        {{$data['name']}}
    @else
        no 
    @endif
</div>

unless

除非if取反

<div>
    @unless ($data['age'] > 20) 
        {{$data['name']}}
    @endunless
</div>

for

<div class="title">
    @for ($i=0; $i<5; $i++)
    {{$i}}
    @endfor
</div>

foreach

@foreach ($data['article'] as $v)
    <div class="title">
    {{$v}} 
    </div>
@endforeach

子视图

include

引入子视图

<html>
    <head>
        <title></title>
    </head>
    <body>
        @include('admin.public.header')
        <div>中间</div>
        @include('admin.public.footer')
    </body>
</html>

传入参数

@include('admin.public.header', ['page' => 'index'])

yield & exnteds

占位视图

<html>
    <head>
        <title></title>
    </head>
    <body>
        
        <div>header</div>
    
        @yield('content')        
        
        <div>footer</div>
        
    </body>
</html>

利用extends,使用占位视图.

@extends('admin.layouts.index')

@section('content')
<div>替换内容</div>    
@endsection()

在主模板定义内容,父模板引用.
主模板:
语法:

@section('name')
    // conent
@show

<html>
    <head>
        <title></title>
    </head>
    <body>
        
        <div>header</div>
    
        @yield('content')        

        
        @section('module')
            <div>主模板</div>
        @show
        
        <div>footer</div>
        
    </body>
</html>

子模板使用:需要在section范围中使用

@extends('admin.layouts.index')

@section('content')
<div>替换内容</div>


@parent
@endsection()

读取配置项

.ENV文件及配置项读取

.env配置项:

APP_ENV=local // 运行环境
APP_DEBUG=true // 调试模式
APP_KEY=iCfdjsHjdgoBp5HS9JmDNWyR1CCSmsu3  // 项目安全配置项的密>钥  // php artisan key:generate
APP_URL=http://localhost // 项目根目录

// 数据库配置项
DB_HOST=127.0.0.1  // 服务器地址
DB_PORT=3306 // 服务器端口
DB_DATABASE=homestead // 数据库
DB_USERNAME=homestead // 用户名
DB_PASSWORD=secret // 密码

// 驱动设置
CACHE_DRIVER=file  // 缓存驱动
SESSION_DRIVER=file // session驱动
QUEUE_DRIVER=sync // 队列模式

// redis 配置
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

// mail 邮件配置
MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

config/app.php
读取使用.env文件

return [
    'debug' => env('APP_DEBUG', false) // 如果`.env`文件中没有配置APP_DEBUG就使用默认值false
]

控制器中读取配置项

public function view() {
    var_dump(config('app.debug'));
    var_dump(config('app.timezone'));
    var_dump(config('database.connections.mysql.port'));
    echo \Illuminate\Support\Facades\Config::get('webConf.web_title'); 
}

数据库

数据库连接

需要引入DB类

use Illuminate\Support\Facades\DB;

测试是否连接成功数据库

$pdo = DB::connection()->getPdo();
dd($pdo);

查询数据

$users = DB::table('user')->get();
$user = DB::table('user')->where('user_id', 1)->get();
$user = DB::table('user')->where('user_id', '>', 2)->get();

Eloquent ORM

模型操作数据库
每张数据表都对应一个与该表进行交互的“模型”,模型允许在表中进行数据查询,以及插入、更新、删除等操作.

创建模型

> php artisan make:model Http/Model/User

查询数据
需要引入User模型

use App\Http\Model\User;

$user = User::where('user_id', 1)->get();

laravel在更新和修改数据的时候,都会增加一个字段update_at或者create_at.表示能够记的更新记录的时间。

解决方法:

  1. 在数据库中增加update_at或者create_at

  2. 在模型中禁止laravel管理数据的方式:public $timestamps = false; // 默认的时间戳禁止

设置数据表名,设置表的主键

<?php

namespace App\Http\Model;

use Illuminate\Database\Eloquent\Model;

class User extends Model {
  protected $table = 'user'; 
    protected $primarykey = 'user_id';
    public $timestamps = false; // 默认的时间戳禁止 
}

find()

查询数据&更新数据

$user = User::find(2); // 查询数据
dd($user); 

$user->user_name = 'color'; // 更新数据
$user->update();

后台功能

验证码

  1. laravel没有开启原生的php的session, 需要在入口文件中开启session.

  2. 引入类,路径问题,需要到基类中寻找 new \Code();

/**
 * 后台登陆验证码
 */
public function code() {
    $code = new \Code();
    echo $code->make();
}

Input服务
Input::all() 获取表单数据

CSRF认证

在提交过程中需要前台传入csrf验证token值字段:{{csrf_field()}}

源码中显示:

<input type="hidden" name="_token" value="mQHCxzs0iB1JkSnhu5OYui11H2McZSRK4iNdCnOK">

Crypt加密和解密
虽然加密过程中一直变化数据,但是有一次结果抓取住就可以解密。
Crypt::encrypt(); Crypt加密
Crypt::decrypt(); Crypt解密

判断登陆逻辑:

/**
* 登陆状态
*/
public function login() {
if ($input = Input::all()) {
    // 判断验证码
      if (strtoupper($input['code']) != strtoupper($this->getCode())) {
          return back()->with('msg', '验证码错误!');
      }
      // 用户名和密码
      if (!$input['user_name'] && !$input['user_pass']) {
          return back()->with('msg', '用户名或密码不能为空!');
      } else {
          // 存在用户名和密码
          // DB::table('user')->where('user_id', $input['user_name'])
          $user = User::first();
          if ($user->user_name != $input['user_name'] || Crypt::decrypt($user->user_pass) != $input['user_pass']) {
                        return back()->with('msg', '用户名或密码不正确!');
          } 
          
                    // 登陆信息写入session中.
                    session(['users' => $user]);
                    
                    // 跳转后台首页
                    return redirect('admin/index');
      }

  } else {
      return view('admin.login');
  }

}

后台首页、欢迎页面修改及子视图布局

Laravel5.2中PHP获取服务器操作系统等信息:
PHP程式版本:<?php echo PHP_VERSION;?>
zend版本:<?php echo zend_version(); ?>
mysql支持 <?php echo function_exists(mysql_close) ? 'y': 'n'?>
服务器操作系统: <?php echo PHP_OS;?>
服务端信息: <?php echo $_SERVER['SERVER_SOFTWARE'];?>
最大上传限制:<?php echo get_cfg_var('upload_max_filesize') ? get_cfg_var('upload_max_filesize') : '不允许上传附件'>
最大执行时间:<?php echo get_cfg_ver('max_execution_time').'秒';?>
脚本运行占用最大内存:<?php echo get_cfg_ver('memory_limit') ? get_cfg_ver('memory_limit') : '无'?>
获得服务器系统时间: date_default_timezone_set(PRC); echo date('Y-m-d G:i:s');
查询当前连接的MYSQL数据库的版本php原生函数mysql_get_server_info();

管理员登陆中间件设置和注销登陆

利用中间件验证登录信息.

注册中间件:app/Htpp/Kernel.php

protected $routeMiddleware = [ ];

利用session判断页面是否可以进入.

public function handle($request, Closure $next) {
    
    // 判断session中的登陆信息
    if (!session('users')) {
        return redirect('admin/login');
    }
  return $next($request);
}

密码修改及Validation验证

Validator服务
引入use Illuminate\Support\Facades\Validator;
Validator::make();

表单验证

public function pass() {
    if ($input = Input::all()) {

        // 验证规则
        $rules = [
            'password' => 'required|between:5,20|confirmed',
        ];

        // 提示信息
        $msg = [
            'password.required' => '新密码不能为空',
            'password.between' => '新密码必须在5-20位之间',
            'password.confirmed' => '新密码和确认密码不一致'
        ];

        $validator = Validator::make($input, $rules, $msg);
        if ($validator->passes()) {
            // 对比原密码
        $user = User::first();
            $_password = Crypt::decrypt($user->user_pass);
        
        // 判断输入的 原始密码和 数据库存储的密码
        if ($input['password_o'] != $_password) {
            return back()->with('msg', '原密码输入错误');        
        }
        
        // 密码修改
        $user->user_pass = $_password = Crypt::encrypt($input['password']);
        $user->update();
        return back()->with('msg', '密码修改成功');
        } else {
//                dd($validator->errors()->all());
            return back()->withErrors($validator);
        }
    } else {
        return view('admin.pass');
    }
}

Category

文章分类表的创建

创建表

DROP TABLE IF EXISTS `b_category`;

CREATE TABLE `b_category` (
  `cate_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `cate_name` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '分类名称',
  `cate_title` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '文字说明',
  `cate_keywords` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '关键词',
  `cate_description` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '描述',
  `cate_view` int(10) NOT NULL DEFAULT '0' COMMENT '查看次数',
  `cate_orer` tinyint(4) NOT NULL DEFAULT '0' COMMENT '排序',
  `cate_pid` int(11) DEFAULT '0' COMMENT '父级id',
  PRIMARY KEY (`cate_id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='文章分类';

后台文章分类页多级分类列表

/**
 * 家谱树
 * @param {Object} $data 传入所有数据
 * @param {String} $field_name  字符串 
 * @param {String} $field_id  cate_id 字段 
 * @param {String} $field_pid  cate_pid 字段  
 * @param {Int} $pid 顶级分类id
 * @return {Array} 相联系的数据
 */
public function getTree($data, $field_name = '-- ', $field_id = 'cate_id', $field_pid = 'cate_pid', $pid = 0) {
    
    // 存放处理后数据
    $arr = array();
    
    /**
     * 1. 遍历 pid为0 (顶级目录) , 压入数组
     * 
     * 2. pid 不为0 的,对比pid,压入数组后续中. 
     */
    
    foreach($data as $k => $v) {
        if ($v[$field_pid] == $pid) {
            $arr[] = $data[$k];
            foreach($data as $m => $n) {
                // 对比 $v[cate_id] 和 $data[cate_pid] 对比
                if ( $n[$field_pid] == $v[$field_id] ) {
                    $data[$m]['_cate_name'] = $field_name; 
                    $arr[] = $data[$m];                        
                }
            }
        }
    }
    return $arr;
}    

Ajax异步修改分类排序
注意需要token字段.

<script type="text/javascript">
// 排序功能
$(function() {
    $('.changeOrder').change(function() {
        $.ajax({
            url: '{{url("admin/cate/changeorder")}}',
            type: 'POST',
            data: {
                _token: '{{csrf_token()}}' // csrf 认证
            },
            success: function(data) {
                console.log('data');
            }
        });
    });
});
</script>

表单数据收集

  1. $input = Input::except('_token'); // 不需要使用某些方法

  2. $input = Input::all();

  3. $input = Input::get('type'); // 获取某个字段

  4. $input = Input::file('Filedata'); // 获取文件中的信息

参数中表单收集数据

public function store(Request $request) {
    // 接收表单数据
    $input = $requset->all();

}

过滤入库数据
在模型中增加属性

protected $guarded = []; // 当前有那些不需要写入数据库. // 开启黑名单
protected $fillable = ['cate_id']; // 开启白名单

form提交put数据
form利用hidden隐藏域

<input type="hidden" name="_method" value="put" />

put接收数据

/**
 * put admin/category/{category} 更新分类
 */
public function update($cate_id) {
    $input = Input::except('_token', '_method');
    $res = Category::where('cate_id', $cate_id)->update($input);
    
    if (!$res) {
        // 更新数据失败
        return back()->with('errors', '添加失败');                
    } else {
        // 更新数据成功
        return redirect('admin/category');
    }
    
}

异步ajax提交delete删除数据

// 异步删除数据
$.ajax({
    url: '{{url("admin/category")}}' + '/' +$cate_id,
    type: 'post',
    data: {
        _token: '{{csrf_token()}}',
        _method: 'delete'    
    },
    success: function(data) {
        console.log(data);
    }
});

后台接收delete数据

/**
 * delete admin/category/{category} 删除单个分类
 */
public function destroy($cate_id) {
    $res = Category::where('cate_id', $cate_id)->delete();

    // 处理顶级分类
    Category::where('cate_pid', $cate_id)->update(['cate_pid' => 0]);

if (!$res) {
    // 删除失败
    $data = [
        'status' => 0,
        'msg' => '分类删除失败'
    ];
    return json_encode($data);
} else {
    // 删除成功
    $data = [
        'status' => 1,
        'msg' => '分类删除成功'
        ];
        return json_encode($data);
    }
}

顶级分类删除处理方式:

  1. 顶级分类需要看是否有下级分类,没有删除,有提示不允许删除

  2. 删除顶级分类,把顶级分类x下一级子分类都调整为顶级分类.

// 处理顶级分类
Category::where('cate_pid', $cate_id)->update(['cate_pid' => 0]);

创建文章表

create table b_article (
    art_id int primary key auto_increment,
    art_title varchar(100) default '' not null  comment '标题',
    art_tags varchar(10)  default '' not null comment '标签',
    art_keywords varchar(100) not null default '' comment "关键词",
    art_description varchar(255) not null default '' comment "描述",
    art_thumb varchar(255) not null default '' comment "缩略图",
    art_content text not null default '' comment "文章内容",
    art_time int(11) not null default 0 comment "发布时间",
    art_editor varchar(50) not null default '' comment "发布作者",
    art_view int(11) not null default 0 comment "查看次数"
) engine myisam charset utf8;

Article

文章分类资源路由

$ php artisan route:list
+--------+--------------------------------+--------------------------------+------------------------+-----------------------------------------------------------+-----------------+
| Domain | Method                         | URI                            | Name                   | Action                                                    | Middleware      |
+--------+--------------------------------+--------------------------------+------------------------+-----------------------------------------------------------+-----------------+
|        | GET|HEAD                       | /                              |                        | App\Http\Controllers\IndexController@index                |                 |
|        | POST                           | admin/article                  | admin.article.store    | App\Http\Controllers\Admin\ArticleController@store        | web,admin.login |
|        | GET|HEAD                       | admin/article                  | admin.article.index    | App\Http\Controllers\Admin\ArticleController@index        | web,admin.login |
|        | GET|HEAD                       | admin/article/create           | admin.article.create   | App\Http\Controllers\Admin\ArticleController@create       | web,admin.login |
|        | GET|HEAD                       | admin/article/{article}        | admin.article.show     | App\Http\Controllers\Admin\ArticleController@show         | web,admin.login |
|        | DELETE                         | admin/article/{article}        | admin.article.destroy  | App\Http\Controllers\Admin\ArticleController@destroy      | web,admin.login |
|        | PUT|PATCH                      | admin/article/{article}        | admin.article.update   | App\Http\Controllers\Admin\ArticleController@update       | web,admin.login |
|        | GET|HEAD                       | admin/article/{article}/edit   | admin.article.edit     | App\Http\Controllers\Admin\ArticleController@edit         | web,admin.login |
+--------+--------------------------------+--------------------------------+------------------------+-----------------------------------------------------------+-----------------+

class CategoryController extends CommonController {

    /**
     * get admin/category 全部分类列表
     */
    public function index() {
    }

    /**
     * get admin/category/create 添加分类 get
     */
    public function create() {
    }

    /**
     * get admin/category/{category} 显示单个分类信息
     */
    public function show() {
    }

    /**
     * delete admin/category/{category} 删除单个分类
     */
    public function destroy($cate_id) {
    }
    

    /**
     * put admin/category/{category} 更新分类
     */
    public function update($cate_id) {
    }

    /**
     * get admin/category/{category}/edit 编辑分类
     */
    public function edit($cate_id) {
    }


    // post admin/category 添加分类 post
    public function store() {

    }

}

引入富文本编辑器

<td>
    <script type="text/javascript" charset="utf-8" src="{{asset('resources/org/ueditor/ueditor.config.js')}}"></script>
    <script type="text/javascript" charset="utf-8" src="{{asset('resources/org/ueditor/ueditor.all.min.js')}}"> </script>
    <script type="text/javascript" charset="utf-8" src="{{asset('resources/org/ueditor/lang/zh-cn/zh-cn.js')}}"></script>

    <script id="editor" type="text/plain" name="art_contenttext" style="width: 860px;height:500px;"></script>

    <script type="text/javascript">
        // 实例化编辑器
        var ue = UE.getEditor('editor');
    </script>

    <style>
        .edui-default{ line-height: 28px; }
        div.edui-combox-body,div.edui-button-body,div.edui-splitbutton-body
        { overflow: hidden; height:20px; }
        div.edui-box{overflow: hidden; height:22px;}
    </style>
</td>
                   

缩略图上传
uploadify插件

展示:

<td>
<script src="{{asset('resources/org/uploadify/jquery.uploadify.min.js')}}" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="{{asset('resources/org/uploadify/uploadify.css')}}">
<input id="file_upload" name="file_upload" type="file" multiple="true">
<script type="text/javascript">
    <?php $timestamp = time();?>
    $(function() {
        $('#file_upload').uploadify({
            'buttonText': '图片上传',
            'formData': {
                'timestamp' : '<?php echo $timestamp;?>',
                '_token': '{{csrf_token()}}',
            },
            'swf'      : '{{asset("resources/org/uploadify/uploadify.swf")}}',
            'uploader' : '{{url('admin/upload')}}' // 上传路径
        });
    });
</script>
<style>
    .uploadify{display:inline-block;}
    .uploadify-button{border:none; border-radius:5px; margin-top:8px;}
    table.add_tab tr td span.uploadify-button-text{color: #FFF; margin:0;}
</style>
</td>

上传:

/**
 * 图片上传
 */
public function uploadImg() {
    $file = Input::file('Filedata');
    // 检验上传的文件是否有效
    if ($file->isValid()) {
        $extension = $file->getClientOriginalExtension(); // 后缀名
        // 自定义目录
        $newName = date('ymdhis').mt_rand(100, 999).'.'.$extension; // 201702191657000000aaa.png
        $path = $file->move(base_path().'/uploads', $newName); // base_path()  项目根目录
        $filePath = '/uploads/'.$newName;
        echo $filePath;
    }
}

laravel普通的文件上传

客户端:
<form method="post" action="" enctype="muitipart/form-data">
    <input type="file" name="myfile">
    <input type="submit" name="submit" value="Submit">
</form>


服务端:

$file = Input::file('myfile');

// 检验上传的文件是否有效
if ($file->isValid()) {
    $clientName = $file->getClientOriginalName(); // 获取文件名
    $tmpName = $file->getFileName(); // 缓存的tmp文件夹中的文件名
    $realPath = $file->getRealPath(); // tmp文件夹中的绝对路径
    $extension = $file->getClientOriginalExtension(); // 后缀名
    $mimeType = $file->getMimeType(); // mime 类型
    $path = $file->move('storage/uploads'); // 移动 // 存放默认位置 `public/storage/uploads/xxxx.tmp`
    // 自定义目录
    $path = $file->move(app_path().'/storage/uploads', $newName); // app_path() 计算的路径是app文件夹所在的路径 // $newName = md5(date('ymdhis').$clientName).'.'.$extension;
}

分页服务

/**
 * GET admin/article
 * 全部文章列表
 */
public function index() {
    // 分页
    $data = Article::orderBy('art_id', 'desc')->paginate(2);
    return view('admin.article.index')->with('data', $data);
}

显示:

<div class="page_list">
    {{$data->links()}}
</div>

实体输出

{!! $title !!}

friendlyLink

使用Migrations数据库迁移创建数据表
数据迁移和数据填充

创建数据表

  • 创建文件

php artisan make:migration create_links_table
  • 书写表信息

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateLinksTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('links', function (Blueprint $table) {
            $table->engine = 'myisam';
            $table->increments('link_id');
            $table->string('link_name')->default('')->comment('名称');
            $table->string('link_title')->default('')->comment('标题');
            $table->string('link_url')->default('')->comment('链接');
            $table->integer('link_order')->default(0)->comment('排序');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('links');
    }
}
  • 执行填充

php artisan migrate

使用Seeding填充测试数据

  • 创建文件

php artisan make:seeder LinksTableSeeder
  • 写入字段

<?php

use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;

class DatabaseSeeder extends Seeder{
    /**
     * 运行数据库填充
     *
     * @return void
     */
    public function run()
    {
        DB::table('users')->insert([
            'name' => str_random(10),
            'email' => str_random(10).'@gmail.com',
            'password' => bcrypt('secret'),
        ]);
    }
}

DatebaseSeeder.php文件中执行

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
         $this->call(LinksTableSeeder::class); // 执行LinksTableSeeder.php文件
    }
}
  • 写入数据库

php artisan db:seed

网站配置模块

  • 统计相关组件

  • 默认图片

  • 列表页版权提示

  • 每天发布文章数

  • 网站状态

  • 配置项标题

网站配置表

create table b_config(
    conf_id int auto_increment primary key,
    conf_title varchar(50) not null default '' comment '配置项标题',
    conf_name varchar(50) not null default '' comment '变量名',
    conf_content text comment  '变量名值',
    conf_order int(11) not null default 0 comment '排序',
    conf_tips varchar(255) not null default '' comment '说明&备注',
    conf_field_type varchar(50) not null default '' comment '字段类型',
    conf_field_value varchar(255) not null default '' comment '字段类型值'
)engine myisam charset utf8;

生成网站配置项文件

/**
 * 生成配置项文件
 */
public function putFile() {
    // echo \Illuminate\Support\Facades\Config::get('webConf.web_title'); // 拿取配置项信息
    // 拿取文件
    $config = Config::pluck('conf_content', 'conf_name')->all(); // 过滤要的字段及信息
      $path = base_path() . '\config\webConf.php';

      // 重组数据 ,写入配置文件
      $str = '<?php return ' . var_export($config, true) . ';';
      // 写入配置文件
      file_put_contents($path, $str);
    
}

模型方法:

$config = Config::pluck('conf_name', 'conf_content'); // 过滤要的字段及信息
$coinfAll = Config:all(); // 获取全部字段及信息

在模板中读取配置项信息

Config::get('web.web_title'); // 文件名.键值
// 获取最新的数据
$data = Article::where('cate_id', $cate_id)->orderBy('art_time', 'desc')->paginate(4);
// 读取子分类
$submenu = Category::where('cate_pid', $cate_id)->get();

// 赋值模板
View::share('$nav', $nav);

laravel函数
dd() 打印消息
back() 返回前一请求,
back()->with('msg', txt) 返回前一个请求,带回信息.
back()->withErrors($validator); 返回前一个请求,带回验证信息.
view() 显示视图页面
confing()读取配置项
session() 获取和设置session字段
redirect() 跳转页面,重定向
base_path()获取根目录文件夹路径
app_path()获取app目录的路径
take() 模型获取指定条数:Article::orderBy('art_view', 'desc')->take(6)->get();

laravel模板中使用的函数
asset()显示静态资源.(css&img&js)
url() 地址引用 (使用/分割目录)
method_field('PUT')提交type

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值