欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

laravel Autoloading 自动加载 有大用 有大用

shiping1 的头像

laravel被说成2013最流行框架,还有用过。打算用laravel做一个小项目,按照之前的习惯,习惯把controller按照功能划分多个目录

比如:

controllers:
     admin:
           DashboardController.php
     web:
           HomeController.php

laravel的route有各种规则,group应用同一组路由,配置如下

1
2
3
4
Route::group(array('prefix' => 'admin', 'namespace' => 'App\Controllers\Admin'), function()
{
    Route::get('/home', 'HomeController@index');
})

admin下的DashboardController.php

1
2
3
4
5
6
7
8
9
10
<?php
namespace App\Controllers\Admin;
 
class DashboardController extends \BaseController{
 
    public function index(){
        echo "test";
        exit;
    }
}

运行,报错 Class 'App\Controllers\Admin\DashboardController' not found

路径和命名都没问题,只有看手册、google、stackoverflow找问题,老半天没结果,网上怎么说的都有;简单看下Router.php代码,也没发现问题。

后来看了http://stackoverflow.com/questions/18132220/laravel-4-package-or-modules,需要dump-autoload,试了下,果然可以。

再回头看下laravel代码,会先加载autoload_classmap.php文件,然后按照该文件找类。现在记录下完整的过程

编辑composer.json文件,添加

"autoload": {
        "classmap": [
            "app/commands",
            "app/controllers",
            "app/controllers/admin",

然后运行: composer dump-autoload

 

如果composer没有安装,参考https://getcomposer.org/doc/01-basic-usage.md,安装下

1
2
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/bin/composer

就可以了

来自  http://my.oschina.net/lewisliang/blog/195194

下面是自己亲自做的 虽然是对的 但是理论上肯定没有上面人家的方法好
ErrorException (E_WARNING)  include(D:\xampputf8\htdocs\laravelstudy4.2-2/app/controllers/MovieController-bak.php): failed to open stream: No such file or directory  

发现 autoload_classmap 内有映射 
关于类名 和 文件名的映射 发现了 MovieController-bak.php 但是没有存在MovieController-bak.php文件



 

Laravel 4 - Package or “modules”?


 

I'm starting to work with Laravel 4, it seems to be a great choice, anyway before coding my first project i'd like to understand if my usual approach could be ok with laravel.

Usually i keep triad for backend and frontend separated under a /modules folder, like this:

/modules
       /backend
               /config
               /controllers
               /models
               /migrations
               /ecc..
       /frontend (and so on...)

With laravel i'm not really sure how to manage this. I'm trying with packages, but the php artisan workbench me/mypackage --resources don't build the entire folder structure... where to put controllers and models, and how to setup routes?

Then i found this link to enable modules-like system. So, what's the approach i should follow for keeping things in the laravel way?

正确答案

Well, let's begin...

First, I created Andreyco\Cart package using Artisan.
Package and it's structure

|workbench
|-andreyco
|---cart
|-----public
|-----src
|-------Andreyco
|---------Cart
|-------config
|-------lang
|-------migrations
|-------views
|-----tests
|-----vendor

In the answers, I will use this exact package as example.

Imagine, that folder workbench/andreyco/cart/src is the application folder. If you do, you should know the most of the answers. (Actually App is package as well)

Q: how to setup routes
A: Create the file -> workbench/andreyco/cart/src/routes.php. This is done.

Q: where to put controllers and models
A: Just create controllers and models folder there.
So the TestController would be located at workbench/andreyco/cart/src/controllers/TestController.php file. Very same with models.
Directory tree would look like this

|workbench
|-andreyco
|---cart
|-----public
|-----src
|-------Andreyco
|---------Cart
|-------config
|-------controlers
|-------lang
|-------migrations
|-------models
|-------views
|-----tests
|-----vendor

I created the routes.phpTestController.php and the TestModel.php

// workbench/andreyco/cart/src/routes.php
<?php

Route::get('test', 'Andreyco\\Cart\\Controllers\\TestController@index');



// workbench/andreyco/cart/src/controllers/TestController.php
<?php namespace Andreyco\Cart\Controllers;

use Andreyco\Cart\Models\TestModel;

class TestController extends \BaseController
{
    public function index()
    {
        return TestModel::printCurrentLocation(__DIR__);
    }
}



// workbench/andreyco/cart/src/models/TestModel.php
<?php namespace Andreyco\Cart\Models;

class TestModel extends \Eloquent
{
    public static function printCurrentLocation($location)
    {
        return "Testing package controller, script is located at: {$location}";
    }
}

As you can see, I used namespaces, so you should.
Namespaces make your life a lot of easier.

Important: after creating those files, you need to update composer.json file, so that classes could be autoloaded

// composer.json
"autoload": {
    "classmap": [
        ...
        "workbench/andreyco/cart/src/controllers",
        "workbench/andreyco/cart/src/models"
    ]
},

After this, dump the changes using composer dump-autoload -o command.

Q: So, what's the approach i should follow for keeping things in the laravel way?
A: In my opinion, you should stick to packages. At least, I would. That's the way Laravel was designed to work.

I hope this helps you, good luck!

Edit
Views are not problem here. They work just like in main app package.

// workbench/cart/src/view/foldername/viewname.blade.php

<h1>Testing view file.</h1>
{{ "Blade" }} syntax is parsed as well, no problem here.

Returning view from package's controller is pretty simple

public function index()
    {
        return \View::make('cart::foldername.viewname');
    }
shareimprove this answer
 
1 
Thanks you Andrej. That was really helpful! So, routes must be namespaced, but why the double slash? – Luciano Aug 9 '13 at 10:43
1 
Double backslash is used to escape `` character. Someone correct me, if I'm wrong. Laravel translates this into namespace correctly – Andreyco Aug 9 '13 at 10:57
   
Apparently I forgot to escape the ` \ ` character in previous comment. – Andreyco Aug 9 '13 at 12:06
   
Ok got it. Seems that routes, if placed inside app/routes.php works without double backslash, anyway now i'm having another doubt: how i use partials view into the package's master template? I've tried namespacing like this @include('backend::_partials.nav') or this @include('backend::_partials/nav') but still not working. – Luciano Aug 9 '13 at 16:14
   
Sorry for being late. I updated the answer with info how to return View object. To answer question about controllers & namespaces: you can use namespaced controllers in app/routes.php as well. You do not have to use namespaces at packages (or app) at all - it's up to you, but namespaces can make your live easier. – Andreyco Aug 11 '13 at 18:07


来自  http://stackoverflow.com/questions/18132220/laravel-4-package-or-modules


普通分类: