I was trying to migrate a Laravel 4.2 app into Laravel 5.0
and previously in Laravel 4.2 you have a BaseController which other Controllers you create can extend, meaning if I add a method inside it. The other controllers will extending the BaseController can use it.
Now on Laravel 5.0, they somehow changed it instead of using class they made use of an abstract class
<?php namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesCommands;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
abstract class Controller extends BaseController {
use DispatchesCommands, ValidatesRequests;
}
Now I'm not familiar with what an abstract class is so my main concert is will I still be able to add functions() that can be used by other controllers extending it?
So as an example in a controller extending the BaseController
$this->method_from_base_controller();
Yes, you can create for abstract classes methods that will be used in classes that inherits from abstract class.
The main difference between abstract classes and normal classes is that you cannot create objects of abstract classes. You can also create in abstract classes methods you want to be implemented in child classes. Reference on abstract clasess on php.net
Related
I have developed a package containing package controllers. Everything is loading and working fine, but currently the package controller looks like this:
<?php
namespace MyPackage\App\Http\Controllers;
use App\Http\Controllers\Controller; // Stock Laravel controller class
use Illuminate\Http\Request;
use Voice\CustomFields\App\Form;
class FormController extends Controller
{
...
}
I want the class to extend Laravel Controller class, however inside my package this class of course doesn't exist as it is a part of a standard Laravel app.
I ended up including use App\Http\Controllers\Controller;, but I don't see it as a good practice since I'm referencing something that doesn't exist up to the point I include my package in the app.
How can I do this the right way? I can replicate the class within my package, but this would be duplicating logic + additional problems if tomorrow a new Laravel version is released with a modified Controller class.
Just look in source code of App\Http\Controllers\Controller
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
You can extend BaseController in your package controllers. If Laravel team change something, it will be written in migration instructions.
If you need some specyfic logic in your package BaseController and the same logic in app BaseController, consider using trait or ServiceProvider.
Your controller doesn't necessarily need to extend the default "base controller". Usually packages either extend the Illuminate\Routing\Controller directly or have their own base controller to extend all the other controllers with.
If you are using the stock base controller without any custom code added, there won't be any duplicate lines if you choose to copy it to your package as it only consists of three optional traits providing helper functions wrapping more complicated code.
How can i overwrite a vendor class?
I'm using Laravel Spark and i wanna have Uuid for all models. Due Spark manage some models inside the package and i don't see a possibility to use my own model for Notifications etc. i would like to overwrite the base Model class from Illuminate\Database\Eloquent\Model, so i could include there my uuid trait.
I tried over the ServiceProvider with:
public function boot()
{
//
$this->app->bind('Illuminate\Database\Eloquent\Model', 'App\Models\Model');
}
But it didn't worked.
Is it possible or maybe exist a better way?
Thanks for any help.
Create a custom model class which will extend the eloquent model.
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class CustomModel extends Model {
// Your implementation
}
And then rest of the models you extend your custom model.
class Test extends CustomModel {
}
I'm using Jacopo Authentication package in one of my sites, I'm extending it to add some methods and do stuff after I call its methods, I'm extending it like this:
<?php
use Jacopo\Authentication\Controllers\UserController as JacopoUserController;
class UserController extends JacopoUserController{
...
}
Now, the problem is that I need to use some methods from my BaseController, whats the best way to be able to use BaseController here? Should I just instantiate it? Maybe move as much logic as I can to a Model or Helper and duplicate a little code? Is there anything like this?
class UserController extends JacopoUserController extends BaseController{
Thank you in advance.
You can extend only one class in PHP. However you could create trait and put there functionality from Basecontroller and to use this functionality simple add use Traitname; to class that needs that functionality
We are looking to build a system with core classes and the ability to extend these core classes and are looking in to using namespaces.
The problem we are having is working out if we can extend an extended class without extending the class that it extends from
For example, if we have folders and files as below
shared/classes/Entity.php
shared/classes/DatabaseEntity.php - Extends Entity.php
shared/classes/User.php - Extends DatabaseEntity.php
classes/ - Holds classes which extend from the shared classes
If we wanted to create a custom DatabaseEntity class without creating a custom User class , is this possible?
The way I understand this is that the User class will be looking in the shared namespace to extend the DatabaseEntity class but as we have extended the DatabaseEntity class, it needs to look at the top level classes directory
Example of shared/classes/User.php
namespace shared;
class User extends DatabaseEntity {
}
Example of shared/classes/DatabaseEntity.php
namespace shared;
abstract class DatabaseEntity extends Entity {
}
Example of classes/DatabaseEntity.php
namespace custom;
use shared\classes\Entity;
abstract class DatabaseEntity extends Entity {
//Some custom functionality to extend shared/DatabaseEntity
}
So if we didn't want to change the User class to say
use custom/DatabaseEntity
Then is this possible?
Hopefully that makes sense
Thanks in advance for any help
If you don't want to add to User class
use custom/DatabaseEntity
and you want to extend custom/DatabaseEntity
you may just change class declaration from
namespace shared;
class User extends DatabaseEntity {
}
to
namespace shared;
class User extends \custom\DatabaseEntity {
}
if you want to extend \custom\DatabaseEntity.
If it's not want you want to achieve I cannot understand your problem - you ask two questions.
You asked
If we wanted to create a custom DatabaseEntity class without creating
a custom User class , is this possible?
The answer is - yes, you just created it in your example. You created custom DatabaseEntity class without creating custom User class.
But if you want to achieve:
it needs to look at the top level classes directory
you need to tell User class to extend specific class - so you will need to extend using fully qualified class or import namespace using use and creating alias
I don't know if I understand you well, but you want to create CustomDatabaseEntity class that will extend DatabaseEntity and you don't want that CustomDatabaseEntity extends User class.
It's of course possible. You can create as many child classes as you want. As User class is defined that it extend DatabaseEntity class it will even don't know that you created CustomDatabaseEntity
I also think that you are using it a bit wrong. If DatabaseEntity have anything common with database and not with User itself, you should rather create Interface DatabaseEntityInterface, those two DatabaseEntity classes should implement interface
and then in User class you should pass it as constructor argument
class User {
protected $dbi;
public function _construct(DatabaseEntityInterface $dbi) {
$this->dbi = $dbi
}
}
and later you can pass to User class either class for shared folder or the one from classes
The default HomeController class is defined using
class HomeController extends BaseController {
However, when a resource controller is created via artisan, the class extends \BaseController instead of BaseController. Why is this, and what is the difference?
class TestResourceController extends \BaseController {
There is no difference (in a default installation). The \ simply tells PHP to use the root namespace instead of any other class with the same name but on a different namespace. If you were to create your own class called BaseController, PHP would not know which class to use unless it were explicity defined by the namespace, i.e. MyNamespace\BaseController.