I have a new installation of Laravel 5. The problem is that it's not recognizing my model classes. I will keep it very simple for solution purposes.
Route::get('test', function() {
$test = boxstyle::all();
....
}
My model is in the app directory
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Boxstyle extends Model {
protected $table = 'boxstyle';
protected $primaryKey = 'key1';
}
I am getting:
class boxstyle not found error
I've been searching all over the internet and can't find a solution. This installation is fresh. This isn't magic and I suspect a configuration issue but I can't find a solution. This works fine in Laravel 4.2 so I know it should work but not working in L5.
Your model is defined inside the App namespace. If the code accessing the model is not in the same namespace as the model, you need to qualify it.
Route::get('test', function() {
$test = \App\Boxstyle::all();
}
Laravel 4 did not define the models and controllers inside namespaces. Your models would have been defined inside the global namespace, so any code also in the global namespace (like your controller) would not need to qualify the model. However, Laravel 5 has made the push to put most everything inside namespaces.
To create a model in Laravel 5 try this,create a folder name "Models" folder under your App folder, now for instance you want to create a Model class for Boxstyle ...under your Models folder create a file name
"BoxstyleModel.php" inside your BoxstyleModel.php should look like this and make sure your inside the folder to namespace your model under the App\Models
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class BoxstyleModel extends Model {
public static function say_hello(){
return "Hello";
}
}
in your Boxstyle Controller to be able to use your BoxstyleModel added this code at the top of your BoxstyleController use App\Models\BoxstyleModel;
now everything should be the same like Laravel 4.X.
Related
I am new to Laravel and would appreciate any help on describing how a Laravel package residing in vendor folder can be extended and wont get affected if I update the package.
I'll try to create a brief guide, and we'll expand if need be.
I suggest putting all of your files inside a separate directory / namespace. You'll benefit from this should you decide to create your own composer package afterwards.
As an example I'll extend bumbummen99/shoppingcart package which forks the great gloudemans/shoppingcart, adding support for Laravel 5.8 and some minor functionality. You will of course first need to install that package:
composer require bumbummen99/shoppingcart
Start by making a couple of folders. You can use any name for folders / classes, this is what I used, relative to the project root:
app/Repositories/ExtendedCart
app/Repositories/ExtendedCart/Facades
Create the file
app/Repositories/ExtendedCart/ExtendedCart.php
This class will extend the package's main class:
namespace App\Repositories\ExtendedCart;
use Gloudemans\Shoppingcart\Cart;
class ExtendedCart extends Cart
{
public function myMethod(){
return 'myMethod';
}
}
Then make your Service Provider. Create the file:
app/Repositories/ExtendedCart/ExtendedCartServiceProvider.php
(I'm not using artisan as generating / moving the provider will produce wrong namespace)
This is your Service Provider content, here you reference the class that extends the package's class. Note you overwrite the binding from the original package.
namespace App\Repositories\ExtendedCart;
use Gloudemans\Shoppingcart\ShoppingcartServiceProvider;
class ExtendedCartServiceProvider extends ShoppingcartServiceProvider
{
public function register()
{
$this->app->bind('cart', 'App\Repositories\ExtendedCart\ExtendedCart');
}
}
Then register your service provider in config/app.php
'providers' => [
...
//Add this line to the end of providers array
App\Repositories\ExtendedCart\ExtendedCartServiceProvider::class,
]
Lastly create a Facade, which will instantiate the class (otherwise you will get non-static method exceptions). Create this file:
app/Repositories/ExtendedCart/Facades/ExtendedCart.php
This is the contents of the file:
namespace App\Repositories\ExtendedCart\Facades;
use Illuminate\Support\Facades\Facade;
class ExtendedCart extends Facade {
protected static function getFacadeAccessor() { return 'cart'; }
}
You're all set to use your extended methods. You can safely upgrade the original package, and you can even use the default facade:
namespace App\Http\Controllers;
use Cart;
class SomeController extends Controller{
public function someFunction(){
Cart::instance('default')->myMethod();
//This should return 'myMethod'
}
}
I hope this helps, good luck!
I have created a new directory Library in root of Laravel.
Inside I put the file with class:
class My {
//
}
So, in controller Laravel I try to get access to this class:
App\Library\My
But Laravel does not determine this path.
This is my code:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use View;
use App\Library\My;
class HomeController extends Controller
{
//
}
A complete and functional example based on the posts here:
1 - Folder and file - Create a folder under app/, in this example we will create a folder called Library.
We will also inside the folder create a file with the name of your class, here we will create a class called My.
So we will have app/Library/My.php
2 - Class and method - Now, for testing, inside the class create a static method called myMethod
<?php
namespace App\Library;
class My
{
public static function myMethod()
{
return 'it\'s work!';
}
}
3 - Controller - Now at the beginning of the Controller, we will declare the namespace of your Class with use:
<?php
namespace App\Http\Controllers;
use App\Library\My;
//rest of the controller code
Finally, to create an instance of the My class, in Controller, a new statement must be used:
//rest of the controller code
public function index()
{
$whatever = new My;
return $whatever::myMethod();
}
As above, make sure it is placed in the App directory and make sure it is properly namespaced e.g.
<?php
$fOne = new \App\library\functions;
$isOk = ($fOne->isOk());
?>
You should create Library folder inside app folder
namespace App\Library\My
app folder is alrdy used psr-4
In your controller
use App\Library\My as My
It's work for me. Hope this answer is helpful
You have to properly namespace your every class.
So you can import your class with use keyword, like so
use App\Library\My;
....
$my = new My();
Or if you've conflicting class name then you can use as keyword to alias the classname while importing
use App\Library\My as MySecond;
....
$my = new MySecond();
And if you want to directly access your class within the method then you can access it like so.
$my = new \App\Library\My();
Note: The leading \ means App was declared in the global scope.
Hi can anyone clarify this for me. I have a rather large Laravel 4 app using a few models. I would like to upgrade to L5 and would simply like to use the same model calls in the controllers.
e.g.
Course::
\Course:: //if controller in a deeper folder
The course model is in App/Models. I've tried a composer mapping App/Models but to no avail.
Thanks
I don't know about anyone else. But in my installation of Laravel 5, my models are defined directly within the app folder. The app directory is psr-4 namespaced as App.
composer.json
"autoload": {
...
"psr-4": {
"App\\": "app/"
}
}
Models are then defined under the App namespace. e.g.
namespace App;
use Illuminate\Database\Eloquent\Model;
class Course extends Model {
}
So you can either:
1: Use the full path to the model whenever you use it:
\App\Course::all();
2: use your model before using it like you normally would:
namespace Your\Namespace;
use App\Course;
class YourClass {
public function yourFunction()
{
Course::all();
}
}
3: Create a folder called Models, put your models in there and make sure that their namespace reflects the path (And then call the model like in options 1 and 2):
// app/Models/Course.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Course extends Model {
}
e.g.
\App\Models\Course::all();
or
namespace Your\Namespace;
use App\Models\Course;
class YourClass {
public function yourFunction()
{
Course::all();
}
}
That's just how namespaces work. If you specify a class PHP will always search for it relative to the current namespace. Unless you prepend a backslash and use the full path or add an import statement at the beginning of your files:
namespace App\Http\Controllers;
use App\Models\Course;
class ...
Or
\App\Models\Course::all();
I should add that many editors and IDEs are able to automatically resolve and import classes, so with the right tools it's not that cumbersome...
Is there a way to prevent using 'use' for everything. In Laravel 4 I never used 'use' and everything just worked. I'm now finding out I have to include everything, even 'DB' use DB. This is extremely frustrating and time consuming looking all this up.
My question is, is there an easier way to include everything?
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Customer;
use DB;
class HomeController extends Controller {
}
?>
Thanks
Not really -- this is the Brave New Namespaced world of PHP 5.3+. Your class file above lives in the App\Http\Controllers namespace, which means when you type something like
$object = new SomeClass;
PHP will assume you mean the class App\Http\Controllers\SomeClass.
You'll either, as you complained about, need to use use, or you'll need to use the full classname (with a leading \ to let PHP know to start from the global namespace) whenever you want to use a class
class HomeController extends Controller {
public function someFunction()
{
$result = \DB::query(...);
$customer = new \App\Models\Customer;
//etc...
}
}
This is question is old but I found you can do this based on information from a tutorial by Tejas Jasani: http://www.theappguruz.com/blog/upgrading-from-laravel-4-2-to-5-in-web
Here are the key steps:
1 - Add the app/Http/Controllers directory to the "autoload" classmap directive of your composer.json file.
"autoload": {
"classmap": [
"database",
"app/Http/Controllers"
],
2 - Remove the namespace from the abstract app/Http/Controllers/Controller.php base class.
3 - In app/Providers/RouteServiceProvider.php file, set the namespace property to null
protected $namespace = null;
4 - Run "composer dump-autoload" from the command line.
The problem:
class PostRepostioryInterface not found for line 4 in PostController.php
or in tinkering with the namespace I've even got class
App\Models\Interfaces\PostRepositoryInterface not found
The questions: How to register a namespace in laravel 4? What do I need to do to get L4 to recognise the classes/interfaces at this namespace?
Larave 3 had a $namespaces static object in ClassLoader where you could add namespaces by
Autoloader::namespaces(array(
'App\Models\Interfaces' => path('app').'models/interfaces',
));
I'm not sure if I have that right for laravel 3 but either way, AutoLoader doesn't exist in Laravel 4 and ClassLoader exists but the method namespaces doesn't exist in ClassLoader in Laravel 4.
I've looked at this but it doesn't seem to work without registering the namespace somehow.
Using namespaces in Laravel 4
Example structure:
app/models/interfaces
PostRepostitoryInterface.php
app/models/repositories
EloquentPostRepository.php
namespaces:
App\Models\Repositories;
App\Models\Interfaces;
the files:
PostRepositoryInterface.php
<?php namespace App\Models\Interfaces;
interface PostRepositoryInterface {
public function all();
public function find($id);
public function store($data);
}
EloquentPostRepository.php
<?php namespace App\Models\Repositories;
use App\Models\Interfaces\PostRepositoryInterface;
class EloquentPostRepository implements PostRepositoryInterface {
public function all()
{
return Post::all();
}
public function find($id)
{
return Post::find($id);
}
public function store($data)
{
return Post::save($data);
}
}
PostController.php
<?php
use App\Models\Interfaces\PostRepositoryInterface;
class PostsController extends BaseController {
public function __construct( PostRepositoryInterface $posts )
{
$this->posts = $posts;
}
Thanks
You probably forgot to do composer dump-autoload. This updates the list of classes Laravel autoloads.
You can read more on composer documentation.
On the laravel irc channel I found out the namespaces should work in L4 without a need for registering them anywhere. This is because the composer dump-autoload adds them to the composer/autoload file for me. So that was not an issue.
The issue turned out to be a typo apparently(I can't find it in the code above but after going through every line copy/pasting the class names and namespaces something changed), and also somehow in my real code I left out the 'use' statement for EloquentPostRepository.php
use App\Models\Interfaces\PostRepositoryInterface;
Now I've hit another wall trying to use the namespaced interface with ioc and the controller constructor (target interface App\Models\Interfaces\PostRepositoryInterface is not instantiable) but I guess that should be a different question.