i would like to know if it is possible to have a function in PHP which returns an interface or a class which contains an interface?
i tried something like this, but it fails
<?php
//class for list of controllers for ACL
class Gestionale_Action_Helper_Crud extends Zend_Controller_Action_Helper_Abstract {
interface crud_controller
{
public function indexAction();
public function modificaAction();
public function cancellaAction();
public function creaAction();
}
public function getCrudInterface(){
return $this->crud_controller;
}
}
what i wanted to do, in zend framework, create an interface that crud controllers must implement, or even better if i could create an abstract controller and have them implement that
thank you
I'd suggest that you use Zend_Rest_Controller instead of creating your own interface.
Zend_Rest_Controller is an abstract class that defines five basic methods you need in a CRUD-controller: index, get, post, put, and delete.
Combined with Zend_Rest_Route it lets you create nice and clean RESTful application.
You can get more reading on Zend_Rest_Controller at http://weierophinney.net/matthew/archives/228-Building-RESTful-Services-with-Zend-Framework.html and http://techchorus.net/create-restful-applications-using-zend-framework
Just place the interface outside of any class (preferably in a different file) and let it be implemented by all your crud-controllers.
<?php
class GrudController implements CrudInterface
{
// ...
}
i'm not sure i get what it is you want to do, but i'm fairly certain you're asking the wrong question. if you simply want to make sure an object implements a certain interface, this is quite easy to do. lets say for example you have some helper method in a class which deals with a crud controller, you just specify the type in the argument list:
class crud_helper {
public function help(crud_controller $cc) {
$cc->indexAction();
}
}
now you can pass any object that is an instance of a class that implements crud_controller to the method help. but no other object.
Related
I currently have an abstract class which i am extending to other controllers. I have a abstract function within the abstract class which takes the value and places it in the __construct.
abstract class Controller extends BaseController {
abstract public function something();
public function __construct(Request $request) {
if (!is_null($this->something())){
$this->global_constructor_usse = $this->something();
}
}
}
My problem is that, on controllers that don't require this abstract function, I am having to place in the empty function.
class ControllerExample extends Controller {
public function something(){
return 'somethinghere';
}
}
Is there anyway to making the abstract function optional, or have a default value?
class EmptyControllerExample extends Controller {
public function something(){}
}
It is not possible to have a abstract method optional, as it is implied in PHP that all abstract methods must have an implementation.
There are legit use cases for optional abstract methods, yes: event handlers, metadata describers, etc. Unfortunately, you'll need to use regular, non-abstract methods with an empty body, and indicate in PHPDoc that they will do nothing unless extended.
Be wary, though: this can very quickly turn into code smell by diffusing a class responsability with their children. If you're dealing with generic events, you can look into Laravel's own event system, or the Observer pattern instead.
Abstract functions in a parent class, should only be used if its required by your application to implement the following method in all controllers who inherits from it, clearly it is not the case.
In this case i would make a trait. Here you create a trait which can be implemented by the classes who needs it. Notice the use keyword usage, use somethingTrait;
trait SomethingTrait
{
public function something()
{
echo "something called";
}
}
class Controller
{
use SomethingTrait;
public function run()
{
$this->something();
}
}
phpfiddle link
Another aproach could be doing a class inheritance structure, if the controllers you want to implement the methods has something in common. Where you would implement your special method in CrmController, where you still would be able to create shared methods in the abstract controller.
AbstractController
|
CrmController
|
CompanyController
For your question, 'Is there anyway to making the abstract function optional or have a default value?' No, and you are down the wrong path if you are trying to make abstract function optional. Hope my suggestions can help.
I am very new to "Advanced Laravel" so to speak, however I do know most of the basics and I am trying to understand what namespacing, interfaces and repositories is all about, since I came across it not so long ago.
However, I am getting the following error, and I have no idea what I am doing wrong:
Class app\models\Interfaces\CategoriesInterface does not exist
Below is my code:
Routes.php
App::bind('App\Models\Interfaces\BaseInterface', 'App\Models\Repositories\BaseRepository');
CategoriesController.php
<?php
use app\models\Interfaces\CategoriesInterface;
class CategoriesController extends BaseController
{
protected $categories;
public function __construct(CategoriesInterface $categories)
{
$this->categories = $categories;
}
BaseInterface.php
<?php
interface BaseInterface
{
public function all();
}
CategoriesInterface.php
<?php namespace App\Models\Interfaces;
interface CategoriesInterface extends BaseInterface { }
CategoriesRepository.php
<?php namespace app\models\Repositories;
use App\Models\Interfaces\CategoriesInterface;
use Categories;
class CategoriesRepository implements CategoriesInterface
{
public function all()
{
$categories = $this->categories->all();
return $categories;
}
}
EloquentCategoriesRepository.php
<?php namespace app\models\Repositories;
use App\Models\Interfaces\CategoriesInterface;
class EloquentCategoriesRepository implements CategoriesInterface {
public function all()
{
return Categories::all();
}
Try name spacing the classes/interfaces properly. EloquentCategoriesRepository.php and CategoriesRepository are having app instead of App in the namespace. And CategoriesController too needs to use App\.. not app\...
I see you are trying to implement the repository pattern, which at first it might seem a bit 'advanced' but it's actually pretty simple.
So the basic idea is to abstract the data layer of your application with the database to make your transitions from one DBS to another(ex. Mysql to Mongo).
In other words your are trying to make the business logic of your application independent to the data layer (Where you query your collections/instances), so when you reach a point that you might want to change your database you can just implement another repository. The Interfaces are there to provide a contract between your application and the data layer.
Laravel implementation of the repository pattern it's pretty straight forward.
Create your interface
Create your interface's repository (actual implementation)
Bind the repository using a service provider class (Or in your case App::bind)
Instantiate the dependency in to your controller using the repository
Don't forget to auto load your namespaces using psr-04.
In your case I think the problem is you are not autoloading the namespace.
Also CategoriesRepository.php & EloquentCategoriesRepository.php are both Eloquent repositories and will return Eloquent collections. To return an array of stdClass (standar PDO) you will have to use the \DB facade.
If my answer does not cover you please take a look here
I have seen some similar questions but I have yet to find a good solution for this from the interface all the way to the controller.
My Problem:
I have a few different kinds of applications that will require restarts, each has its own logic for restarting the application(SSH,API calls, etc.). I have set up an interface because although different logic, they all will need some similar functions. I have also created 3 classes, one for each app that implements that interface. where I am having issues is understanding the best way to keep the logic as abstracted from the controller as possible.
Some Questions:
Should I also be creating an Abstract class?
Should this be one controller that handles all types and chooses the correct one?
do I simply inject the different classes into the controller?
Code:
RestartInterface.php
<?php namespace Application\Service\Restart;
interface RestartInterface {
public function start();
public function stop();
public function restart();
}
example of implementing class:
<?php namespace Application\Service\Restart\AppOne;
use Application\Service\Restart\RestartInterface;
class AppOneRestart implements RestartInterface {
public function start() {
}
public function stop() {
}
public function restart() {
}
}
How could I use a service provider to keep this as modular as possible?
What is the best practice in this situation, I would like to be able to use many or as little restart implementations as I want.
thanks!
An abstract class is a way to create a base class you don't need your developers instantiating directly because, usually, there is still missing code from it, like, methods were not fully implemented. So you create an abstract which implements the common methods of your concrete restart classes
abstract class Restart {
public function restart() {
}
}
And then you implement one by one of those classes extending your abstract and creating the missing methods:
class AppOneRestart extends Restart implements RestartInterface {
public function start() {
}
public function stop() {
}
}
Option 1
If your whole application can use a single implementation of it and you just need the ability to swap from one to another, because your business somehow changed, a simple binding will do the trick:
App::bind('RestartInterface', 'AppOneRestart');
Option 2
If during a request you might need one or another, you probably will need to implement the Factory pattern: http://en.wikipedia.org/wiki/Factory_method_pattern, so you inject the factory in your controller:
class RestartApiController extends Controller {
public function __construct(RestartFactory $factory)
{
$this->restart = $factory->make('api');
}
}
I am trying to work out the best way to design my classes and I think abstract classes it the right way here, but I'm not sure! I am building a plugin for Wordpress carts that at the moment, will work for both Woocommerce and WP-Ecommerce. As these two systems have different implementations of certain functionality, such as getting an order object, I want to create a separate class for each platform.
I have the following which will contain generic methods that should be available to the classes that inherit from it. This class should never be instantiated:
class Order_Export {
}
I then have 2 more classes that will inherit from the above:
class Order_WooExport extends Order_Export {
}
class Order_WPExport extends Order_Export{
}
Is my design right here? Am I right in saying the class Order_Export should be an abstract class? What about methods that I want the class inheriting to implement? Do I simply mark the signature in the abstract class and not provide a body, or do interfaces come into play somewhere here?
How about instantiating the right class? Do I create a factory that will return one or the other?
Any advice appreciated!
That sound correct to use abstract base class, as long as you are sure to never need to instantiate Order_Export :
abstract class Order_Export
{
abstract protected function someMeth1();
abstract protected function someMeth2();
public function someMeth3() {
// Do common thing to both Order_WooExport and Order_WPExport
// using someMeth1(), someMeth2()...
}
}
Then :
class Order_WooExport extends Order_Export
{
protected function someMeth1() {
// Do something specific
}
protected function someMeth2() {
// Do something specific
}
}
Finally, the factory seems to be the right way to go too.
I am creating a reporting library in PHP and developed an abstract class named ReportView. This will provide the basic functionality of a report like Generating header and footer, create parameter form.
There will be another function named generate_report in this class. Currently it is empty in abstract class as at this level we do not know the contents of report. Further it includes a render function which calls this generate_report function and sends output to browser.
So I need whenever a child class inherits from ReportView it must implement
the generate_report method otherwise PHP must give error. Is there any keyword or method through which we can enforce implemetation of a specific function.
Do the following:
abstract class ReportView {
abstract protected function generate_report();
// snip ...
}
class Report extends ReportView {
protected function generate_report() { /* snip */ }
}
Any class that extends ReportView and is not abstract must implement generate_report (and any other abstract function in its super classes for that matter).
Sounds like you’d be better off creating an interface, which would enforce you to define those methods in classes that then implement this interface.
<?php
interface ReportInterface {
public function generate();
}
class MyReportClass implements ReportInterface {
}
Instantiating MyReportClass here will throw a fatal error, telling you generate() has not been implemented.
Edit: You can also create abstract classes that implement this interface. You can have your abstract class contain any methods all extending classes need, and have your interface define any methods you need to be defined by extending classes.
You need to declare the method as abstract as well (and don't give it a method body), otherwise the derived classes will not be forced to implement it.
Alternatively, you could implement the method but have it just throw an Exception (not sure why you would want to do this).
Lastly, if all the methods in your base class are "abstract" (do not have bodies) then you can make the class into an Interface instead.