1. View separation and nesting
Run the command under the learnlaravel folder:
php artisan generate:view admin._layouts.default
At this time, the generator plug-in helped us create the app/views/admin/_layouts/default.blade.php file and modified the content to:
<!doctype html><br><html><br><head><br> <meta charset="utf-8"><br> <title>Learn Laravel 4</title><br> @include('admin._partials.assets')<br></head><br><body><br><div class="container"><br> <div class="navbar navbar-inverse navbar-fixed-top"><br> <div class="navbar-inner"><br> <div class="container"><br> <a class="brand" href="{{ URL::route('admin.pages.index') }}">Learn Laravel 4</a><br> @include('admin._partials.navigation')<br> </div><br> </div><br></div><br><hr><br> @yield('main')<br></div><br></body><br></html>
This is the view file, the V in MVC. Views need to be talked about in detail.
The views folder is a view folder. View folders can be nested. Just like I did above, I created the admin/_layout nested folder and created a file called default.blade.php in it. Then we will When this view is used anywhere in Laravel, it is called admin._layouts.default.
We see that the seventh line of the above code is "@include('admin._partials.assets')". Based on the knowledge we just learned above, this means that another file is loaded. Blade is Laravel's template engine. @include here means to directly bring in all the code of that file and put it here, making it part of the current view.
Pay attention to line 25 "@yield('main')". What does this mean? This one is a bit complicated, but we’ll talk about it later.
2. Permission verification
Laravel supports standard HTTP authentication, but here we need to build a blog system, so we will write a complete administrator login system to log in from the page.
Use the command line to create the app/views/admin/auth/login.blade.php file. The code is as follows:
@extends('admin._layouts.default')<br>@section('main')<br> <div id="login" class="login"><br> {{ Form::open() }}<br> @if ($errors->has('login'))<br> <div class="alert alert-error">{{ $errors->first('login', ':message') }}</div><br> @endif<br> <div class="control-group"><br> {{ Form::label('email', 'Email') }}<br> <div class="controls"><br> {{ Form::text('email') }}<br> </div><br> </div><br> <div class="control-group"><br> {{ Form::label('password', 'Password') }}<br> <div class="controls"><br> {{ Form::password('password') }}<br> </div><br> </div><br> <div class="form-actions"><br> {{ Form::submit('Login', array('class' => 'btn btn-inverse btn-login')) }}<br> </div><br> {{ Form::close() }}<br> </div><br>@stop
You should have noticed the first two lines:
@extends('admin._layouts.default')@section('main')
What does this mean? In fact, we will learn in the future that when calling view in the controller, only the login.blade.php file is called. The first line indicates that this view is a subview of admin._layouts.default. At this time, the blade engine will How to assemble this view after loading it? At this time, the following @section('main') should appear, and the code wrapped by it will be directly placed in @yield('main') in admin._layouts.default. Section and yield can be combined arbitrarily. As long as there is a calling relationship between the two views, they can be used in this way, which is very flexible.
Writing this, you may have a question, why are there so many blank lines in the sample code? This is personal experience. All tags in the blade engine will be processed with regular expressions when the view is compiled. There is a problem in the engine itself, which is not a bug. It is that the newline characters will be processed, causing the previous and next lines and this line to be tightly squeezed together. When browsing on the front end, When "View Source Code" in the browser is not clear, adding blank lines before and after can solve this problem. Of course this may be an automatic "compression" feature and will not be discussed in depth.
Add the controller file app/controllers/admin/AuthController.php, then someone said, I know this, haha, run
“php artisan generate:controller admin.AuthController”
This idea is right, but can you try running it? A "admin.AuthController.php" file will be created directly in the app/controllers directory. Someone said, "I'll just use "admin/AuthController". Can you try it? Nope either. So we need to manually create the admin folder under app/controllers first. At this time, enter on the command line:
php artisan generate:controller admin/AuthController
That’s it. Next, rewrite the content of AuthController.php as:
<?php<br />namespace App\Controllers\Admin;<br />use Auth, BaseController, Form, Input, Redirect, Sentry, View;<br />class AuthController extends BaseController {<br /> /**<br /> * 显示登录页面<br /> * @return View<br /> */<br /> public function getLogin()<br /> {<br /> return View::make('admin.auth.login');<br /> }<br /> /**<br /> * POST 登录验证<br /> * @return Redirect<br /> */<br /> public function postLogin()<br /> {<br /> $credentials = array(<br /> 'email' => Input::get('email'),<br> 'password' => Input::get('password')<br> );<br> try<br> {<br> $user = Sentry::authenticate($credentials, false);<br> if ($user)<br> {<br> return Redirect::route('admin.pages.index');<br> }<br> }<br> catch(\Exception $e)<br> {<br> return Redirect::route('admin.login')->withErrors(array('login' => $e->getMessage()));<br> }<br> }<br> /**<br> * 注销<br> * @return Redirect<br> */<br> public function getLogout()<br> {<br> Sentry::logout();<br> return Redirect::route('admin.login');<br> }<br>}
This is our login and logout controller, C in MVC. Next, I will explain the namespace, which is the foundation of Laravel, or the foundation of composer. It is the focus and difficulty of the entire Laravel tutorial. I hope everyone will be careful and don't let anything go if you don't understand. You can ask questions under the corresponding posts on the phphub forum or golaravel forum, or post questions directly.
We first observe the location of this file. It is located in the app/controllers/admin directory. What is the difference? In other frameworks such as CI, subfolders can be directly called by adding the folder name, although there can only be one level at most. But Laravel is not that simple, involving the PHP namespace.
1. Composer supports PSR-0 and PSR-4 standards. The standard stipulates that PHP packages are distinguished by namespaces and provide external services. All exposed classes should be under the author name package name namespace, such as the luiMFFCMail class. . In this way, even packages with the same name by different authors can coexist on https://packagist.org/ for everyone to use.
2. The namespace can be compared to a directory in a Linux system. In any directory, you can directly use the file name to open all files and executable programs in the current directory. If you need to open files in other directories, you need to use Absolute path or relative path.
3. You may have seen in many other tutorials that there is no namesapce statement in the controller header, let alone a bunch of use xxx, like this file https://github.com/cecoo/laravel4demo/blob/master/ app/controllers/BlogController.php. This file directly uses the Blog class on line 8. Why is this?
因为他们都已经在 learnlaravel 这个 composer 应用的配置文件中声明为自动加载了,而他们没有在顶部声明他们所在的命名空间,这样就会被自动加为顶级命名空间。这个配置文件是 composer.json,对象配置项为autoload 下的classmap 项。这个声明会让 Composer 在生成自动载入文件的时候,自动扫描该文件下所有的类以及所有子文件夹中的类,只要没有声明特定的命名空间,将会被自动加载为顶级空间。【之前表述有误,特此更正!】
关于命名空间更多详情,可以参考 【PHP 命名空间 入门】。
OK,到目前为止我们的MVC三元素已经集齐了,那接下来该做什么了呢?配置路由。这里的路由并不是家里用的无线路由 :-D,而是 用户请求的URL到控制器某个方法的转换,function是PHP中代码段的最小单位,所以用户请求的一个路径,如 http://ooxx.com/fuck/me ,这条URL打给路由之后,路由就会去解析,应该调用哪个function,最终返回结果给用户。
Laravel的路由采用闭包的方式返回结果,在app/routes.php 中增加下列内容:
Route::get('admin/logout', array('as' => 'admin.logout', 'uses' => 'App\Controllers\Admin\AuthController@getLogout'));<br>Route::get('admin/login', array('as' => 'admin.login', 'uses' => 'App\Controllers\Admin\AuthController@getLogin'));<br>Route::post('admin/login', array('as' => 'admin.login.post', 'uses' => 'App\Controllers\Admin\AuthController@postLogin'));<br>Route::group(array('prefix' => 'admin', 'before' => 'auth.admin'), function()<br>{<br> Route::any('/', 'App\Controllers\Admin\PagesController@index');<br> Route::resource('articles', 'App\Controllers\Admin\ArticlesController');<br> Route::resource('pages', 'App\Controllers\Admin\PagesController');<br>});
前三条的意思是hold住两个get请求和一个post请求,下面是一个路由组,规定了一个前缀admin,增加了一个过滤器,auth.admin,内部有一个能同时适应get和post请求的‘/'路径,其完整路径是 http://ooxx.com/admin/。剩下的两个资源控制器本质上只是一种简写,URL和控制器类中的方法名的对应表见 资源控制器。
上面说的那个过滤器 auth.admin,是Laravel提供的一个请求过滤器,这个文件就在路由文件的旁边,app/filters.php,在文件末尾增加:
Route::filter('auth.admin', function()<br>{<br> if ( ! Sentry::check()) {<br> return Redirect::route('admin.login');<br> }<br>});
这样我们的权限验证就完成了。上面的代码意思是,在进入这个路由组中的任何一条路由之前,会先过一遍 auth.admin这个filter,这个filter会调用Sentry::check(),如果为false,将会进入if代码块,将用户的请求跳转到 命名路由‘admin.login',命名路由文档。从这个命名路由的名称大家也能看出来,就是跟访客说:傻逼,干啥呢,登录去~
这里的“命名路由”功能是为了模仿 Ruby On Rails 的 “link_to”到对象 的路由绑定功能,无奈PHP上传即部署无守护进程的特性,使得我们没法维护一个全量代码的路由表,没法像Rails那样实现 资源路由-资源对象-路由调用 三者绑定的功能,只能搞出一个半成品命名路由,人为地解决了当调整 /people 到 /human 时,要求名称改变而功能不变,同时要求代码自适应的需求。
这时候,我们就可以尝试访问我们的项目了。推荐配置Apache将一个端口指向learnlaravel这个项目的public目录下,即项目通过 http://127.0.0.1:8080 这样的地址访问,十分不建议从子文件夹访问。如果你不会,可以运行
php artisan serve
启动PHP5.4的内建HTTP服务器。地址将会是http://localhost:8000,注意此处 127.0.0.1 不可以访问。
下面,我们在浏览器中访问 /admin,注意URL会自动跳转到 /admin/login,这说明我们的filter起作用了,但你可能得到以下页面
这说明代码出错了。接下来我们修改 app/config/app.php 第一项为:
'debug' => true,
刷新页面,错误提示出来了!有没有感觉Laravel4.2的错误提示很好看啊,确实不错,但我觉得没有4.1之前的好看 :-D。我得到了如下错误:
说“App\Controllers\Admin\AuthController”这个类未找到,这是为什么呢?这个文件明明有啊。
这就涉及到了另一个问题,Laravel中的autoload问题。Laravel基于命名空间,它只会自动加载所有顶级命名空间的类,就是说我们新增的这个控制器类不是在顶级命名空间下,所以就需要告诉Laravel,我这个类是存在的,怎么告诉它呢?运行
composer dump-autoload
可以了,刷新页面,他告诉我
View [admin._partials.assets] not found.
这个确实是,我们还没建立这个文件呢。建立一个空文件即可,如果是用generator建的话,别忘了把里面默认的内容删掉哦。再刷新页面,如果还有问题,我相信这个问题你可以自己解决。
OK,一个丑的一逼的页面出现了,为什么它这么丑?(鸽子为什么这么大?)因为我们没有引入任何css和js文件,甚至连导航栏的html都不完整。这不要紧,来,按照我github上的代码,自己复制到相应文件中吧。另外,非常重要的一点,把我的项目中的public文件下的 js 和 css 两个文件夹完全复制到你们的public文件夹中。
再刷新,如果你看到以下页面,说明你成功了!
3. 尝试登录
用seed新增一名管理员,顺便新增一个管理员组。新建app/database/seeds/SentrySeeder.php,内容为:
<?php<br />class SentrySeeder extends Seeder {<br /> public function run()<br /> {<br /> DB::table('users')->delete();<br> DB::table('groups')->delete();<br> DB::table('users_groups')->delete();<br> Sentry::getUserProvider()->create(array(<br> 'email' => 'oo@xx.com',<br> 'password' => "ooxx",<br> 'first_name' => 'OO',<br> 'last_name' => 'XX',<br> 'activated' => 1,<br> ));<br> Sentry::getGroupProvider()->create(array(<br> 'name' => 'Admin',<br> 'permissions' => ['admin' => 1],<br> ));<br> // 将用户加入用户组<br> $adminUser = Sentry::getUserProvider()->findByLogin('oo@xx.com');<br> $adminGroup = Sentry::getGroupProvider()->findByName('Admin');<br> $adminUser->addGroup($adminGroup);<br> }<br>}
给app/database/seeds/DatabaseSeeder.php 新增一行:
$this->call('SentrySeeder');
然后运行:
php artisan db:seed
成功以后,进数据库就会发现,users、groups、users_groups表均新增了一行。但是,articles和pages表也分别新增了10行,对,seed就是这么蠢萌^_^
让我们来尝试登录!如果你得到:
Class App\Controllers\Admin\PagesController does not exist
这说明你成功了!
它可以让你从面条一样杂乱的代码中解脱出来;它可以帮你构建一个完美的网络APP,而且每行代码都可以简洁、富于表达力。1、Bundle是Laravel的扩展包组织形式或称呼。Laravel的扩展包仓库已经相当成熟了,可以很容易的帮你把扩展包(bundle)安装到你的应用中。你可以选择下载一个扩展包(bundle)然后拷贝到bundles目录,或者通过命令行工具“Artisan”自动安装。2、在Laravel中已经具有了一套高级的PHP ActiveRecord实现 -- Eloquent ORM。它能方便的将“约束(constraints)”应用到关系的双方,这样你就具有了对数据的完全控制,而且享受到ActiveRecord的所有便利。Eloquent原生支持Fluent中查询构造器(query-builder)的所有方法。3、应用逻辑(Application Logic)可以在控制器(controllers)中实现,也可以直接集成到路由(route)声明中,并且语法和Sinatra框架类似。Laravel的设计理念是:给开发者以最大的灵活性,既能创建非常小的网站也能构建大型的企业应用。4、反向路由(Reverse Routing)赋予你通过路由(routes)名称创建链接(URI)的能力。只需使用路由名称(route name),Laravel就会自动帮你创建正确的URI。这样你就可以随时改变你的路由(routes),Laravel会帮你自动更新所有相关的链接。5、Restful控制器(Restful Controllers)是一项区分GET和POST请求逻辑的可选方式。比如在一个用户登陆逻辑中,你声明了一个get_login()的动作(action)来处理获取登陆页面的服务;同时也声明了一个post_login()动作(action)来校验表单POST过来的数据,并且在验证之后,做出重新转向(redirect)到登陆页面还是转向控制台的决定。6、自动加载类(Class Auto-loading)简化了类(class)的加载工作,以后就可以不用去维护自动加载配置表和非必须的组件加载工作了。当你想加载任何库(library)或模型(model)时,立即使用就行了,Laravel会自动帮你加载需要的文件。7、视图组装器(View Composers)本质上就是一段代码,这段代码在视图(View)加载时会自动执行。最好的例子就是博客中的侧边随机文章推荐,“视图组装器”中包含了加载随机文章推荐的逻辑,这样,你只需要加载内容区域的视图(view)就行了,其它的事情Laravel会帮你自动完成。8、反向控制容器(IoC container)提供了生成新对象、随时实例化对象、访问单例(singleton)对象的便捷方式。反向控制(IoC)意味着你几乎不需要特意去加载外部的库(libraries),就可以在代码中的任意位置访问这些对象,并且不需要忍受繁杂、冗余的代码结构。9、迁移(Migrations)就像是版本控制(version control)工具,不过,它管理的是数据库范式,并且直接集成在了Laravel中。你可以使用“Artisan”命令行工具生成、执行“迁移”指令。当你的小组成员改变了数据库范式的时候,你就可以轻松的通过版本控制工具更新当前工程,然后执行“迁移指令即可,好了,你的数据库已经是最新的了!11、自动分页(Automatic Pagination)功能避免了在你的业务逻辑中混入大量无关分页配置代码。方便的是不需要记住当前页......余下全文>>
It can free you from messy codes like noodles; it can help you build a perfect network APP, and every line of code can be concise and expressive. 1. Bundle is the organization form or name of Laravel's expansion package. Laravel's extension package repository is quite mature and can easily help you install extension packages (bundles) into your application. You can choose to download an extension package (bundle) and copy it to the bundles directory, or install it automatically through the command line tool "Artisan". 2. Laravel already has a set of advanced PHP ActiveRecord implementation - Eloquent ORM. It can easily apply "constraints" to both sides of the relationship, so that you have complete control over the data and enjoy all the conveniences of ActiveRecord. Eloquent natively supports all methods of the query builder (query-builder) in Fluent. 3. Application logic can be implemented in controllers or directly integrated into route statements, and the syntax is similar to the Sinatra framework. Laravel's design philosophy is to give developers maximum flexibility, allowing them to create very small websites and build large-scale enterprise applications. 4. Reverse Routing gives you the ability to create links (URIs) through route names. Just use the route name and Laravel will automatically create the correct URI for you. This way you can change your routes at any time, and Laravel will automatically update all related links for you. 5. Restful Controllers are an optional way to distinguish GET and POST request logic. For example, in a user login logic, you declare a get_login() action to process the service of obtaining the login page; you also declare a post_login() action to verify the data POSTed from the form, and After validation, a decision is made to redirect to the login page or to the console. 6. Class Auto-loading simplifies the loading of classes. In the future, you no longer need to maintain the auto-loading configuration table and unnecessary component loading. When you want to load any library or model, just use it immediately, and Laravel will automatically load the required files for you. 7. View Composers are essentially a piece of code that is automatically executed when the View is loaded. The best example is the random article recommendation on the side of the blog. The "view assembler" contains the logic for loading the random article recommendation. In this way, you only need to load the view of the content area, and Laravel will do the other things. Complete it automatically for you. 8. The reverse control container (IoC container) provides a convenient way to generate new objects, instantiate objects at any time, and access singleton objects. Inverse control (IoC) means that you almost don't need to load external libraries (libraries), you can access these objects anywhere in the code, and you don't need to endure complicated and redundant code structures. 9. Migrations is like a version control tool, but it manages the database paradigm and is directly integrated into Laravel. You can use the "Artisan" command line tool to generate and execute "migration" instructions. When your team members change the database paradigm, you can easily update the current project through the version control tool, and then execute the "migration command. Well, your database is already up to date! 11. Automatic paging ( Automatic Pagination) function avoids mixing a lot of irrelevant paging configuration code in your business logic. The convenience is that you don’t need to remember the current page... The rest of the text >>