2015-04-03 3 views
-1

Я хочу добавить в модель аксессуаров и мутаторов. В Laravel 4 все получилось отлично, но с Laravel 5 у меня проблемы. У меня есть папка «lib» в моем каталоге приложений, которая содержит файл «db_transformers.php». Этот файл содержит классы типа «dbDate» с функцией set и get для преобразования дат, хранящихся в базе данных, в удобный для пользователя формат.«Класс не найден» Что я пропустил?

Файл "db_transformers.php" находится в пространстве имен:

<?php namespace App\lib;  

I также rerfer к папке в моей модели:

use App\lib; 

Но мои methodes еще забросить ошибки:

public function getDateTimeAttribute($value) 
{ 
    return dbDate::get($value); 
} 

Это вернет ошибку «Class 'App \ dbDate« not found ».

Что может быть моей проблемой?

+0

try composer dump-autoload – Ymartin

+0

Не делает ничего ... – LuMa

ответ

2

Вы вводите в заблуждение автозагрузку (включая PHP, включая/требующий файл определения класса) с пространствами имен (система, которая позволяет иерархически называть классы/функции PHP, чтобы предотвратить конфликты кода).

Это непростая вещь. Покрытие изменений в автозагрузке в Laravel 5 выходит за рамки вопроса о переполнении стека, но если вам интересно, я написал несколько серий статей по адресу how autoloading works with composer/Laravel 4/Laravel 5.

Для вашего конкретного вопроса, вы говорите, что вы определили класс с именем dbDate в файле с именем db_transformers.php и db_transformers.php имеет пространство имен App\lib.

#File: lib/db_transformers.php 
namespace App\lib; 
//other code 
class dbDate 
{ 
    //other code 
} 
//other code 

Это означает, полное имя вашего класса является App\lib\dbDate. вся вещь - это имя класса. Это, наверное, самая большая вещь, чтобы привыкнуть к пространствам имен в PHP.

Это означает, что если вы хотите использовать класс в другом коде, вам нужно будет обратиться к полному имени класса, включая ведущую обратную косую черту.

return \App\lib\DbDate::get($value); 

Можно также импортировать класс с помощью ключевого слова use

use App\lib\DbDate; 
//other code 
public function getDateTimeAttribute($value) 
{ 
    //since we imported the class with `use`, we don't need to type the full name 
    return DbDate::get($value); 
} 

The используйте ключевые слова импортирует определенный класс в текущем пространстве имен.Когда вы сказали

use App\lib; 

вы говорили PHP

Вы знаете, что глобальный класс App\lib? Я буду ссылаться на него ниже, как lib

Поскольку вы не имеете класс с именем lib, это не имеет смысла, и именно поэтому ваш use не помогло.

Так что это пространства имен. Другая проблема, которую вам нужно решить, - автозагрузка. Автозагрузка - это то, что позволяет пропустить инструкцию или функцию require или include, если вы хотите, чтобы файлы определения класса в вашем проекте.

Laravel 4 использовал кучу различных автозагрузчиков, в том числе что-то вроде автозагрузчика classmap. Автозагрузчик classmap автоматически анализирует все файлы в вашем проекте, ищущие классы, и создает гигантскую карту того класса, где (это немного упрощает его, см. Ссылку , с которой я связывался ранее для получения полной информации).

В Laravel 4 автозагрузчик classmap, возможно, читает файл в lib для вас. Laravel 5 reduced the number of autoloaders, который включал избавление от автозагрузчика classmap для большинства папок.

Самое простое, что вы можете сделать в Laravel 5 - это настроить ваш проект на использование автозагрузчика classmap. Открывают composer.json и найти этот раздел

"autoload": { 
      "classmap": [ 
        "database" 
      ], 
      "psr-4": { 
        "App\\": "app/" 
      } 
    }, 

И добавить lib в раздел classmap автопогрузчика

"autoload": { 
      "classmap": [ 
        "database", 
        "lib" 
      ], 
      "psr-4": { 
        "App\\": "app/" 
      } 
    }, 

Это говорит композитор включать lib папки, когда он создает свои автозагрузчика файлы. Вам нужно запустить команду dumpautoload

composer dump-autoload 

после делать это, и вы должны быть в состоянии использовать классы, определенные в lib/db_transformers.php, как вы хотите.

+0

Спасибо, большое объяснение :) Я многому научился от вашего ответа! Всего один момент, я добавил «приложение/lib», а не «приложение» к карте классов;) Еще раз спасибо :) – LuMa

0

Вы должны использовать полное имя класса: use App\lib\dbDate;

Вы также можете посмотреть в использовании вида декораторов для этой цели, как это делать в вашей модели на самом деле не подходит.

Существует несколько пакетов, которые могут помочь с этим, например. https://github.com/ShawnMcCool/laravel-auto-presenter

Смежные вопросы