class instantiation for use across all models in Laravel3 - php

I am using Laravel 3 (new to it). I have an API helper class that I'm using as a library. I want to have that class instantiated so I can use it within all my models to access the API. I am struggling with figuring out how to do it without instantiating it once in each model. An example would be awesome. Thanks.

There are a few ways you can go about doing this, the easiest would probably be just creating a base model where you instantiate the API helper class, then extending that base model for all of the models which you want to access the API.
It might look something like:
// base.php
class Base {
public static function api()
{
return new YourApiClass;
}
}
// user.php
class User extends Base {
public static function name()
{
return parent::api()->callApiMethod();
}
}
You could also use Laravel 3's IoC container, which might be the better choice depending on what you are doing.

Use an IoC container.
Instantiate your class:
IoC::register('mailer', function()
{
$transport = Swift_MailTransport::newInstance();
return Swift_Mailer::newInstance($transport);
});
And then when you need to access your instance you just have to:
IoC::instance('mailer', $instance);
Reference: http://laravel.com/docs/ioc

Related

How do I inject a request into a facade class in Laravel?

So I have the following class that's a facade:
namespace App\Helpers;
use App\Http\Requests\HomepageRequest;
class Params {
public function __construct(HomepageRequest $request) {
}
Then I have the ParamsServiceProvider class which instantiates the facade class on script startup:
public function register()
{
//
App::bind('params', function() {
return new Params();
});
}
edit: here is the actual facade for the Params class
use Illuminate\Support\Facades\Facade;
class Params extends Facade {
protected static function getFacadeAccessor() {
return 'params';
}
}
This all works fine, the class is instantiated properly, however, it doesn't seem to inject the request object in the constructor like it would in a controller class. Is there a way to inject the request into a facade class like you would in a controller? With the current code, I get the following error:
Too few arguments to function App\Helpers\Params::__construct(), 0
passed in /var/www/v4api/html/app/Providers/ParamsServiceProvider.php
on line 21 and exactly 1 expected
I want to avoid having to manually pass the request input into the class and just have it automatically be injected in the constructor. Any help that you guys can give would be appreciated!
Looks like this worked out:
In the ParamsServiceProvider, instead of using App::bind to instantiate the Params class, do this instead:
public function register()
{
App::alias(Params::class, 'params');
}
then the request object will be injected properly into the facade.
The class you've posted isn't actually a Facade - it's just a regular class.
Because you've type-hinted it's dependencies you don't need to tell Laravel how to create an instance of it - it can work it out all by itself.
You can either inject that class into a controller method (where Laravel will new it up for you), or you can call app(App\Helpers\Params::class) and it will return a new instance of the class for you.
Read more on creating facade classes if you want to create an actual facade. Alternatively you can create a realtime facade - where you instead reference Facades\App\Helpers\Params::foo() and Laravel will let you use the method as if you had an instance of that class.
You have a number options here - point the facade straight to the underlying class and let Laravel work out how to build it, explicitly bind it to the container, or use a realtime facade. Let's go through each.
class Params extends Facade
{
protected static function getFacadeAccessor()
{
return \App\Helpers\Params::class;
}
}
This option points the facade straight to the class you intend it to be a facade for and Laravel will work out the rest.
Alternatively, you can keep it as params and instead fix the binding in the container.
The first example use's Laravel's container to make an instance of the class and return it. Laravel can automatically reflect the class and inject it's dependencies.
App::bind('params', function ($app) {
return $app->make(Params::class);
});
The second example explicitly builds the instance the way you desire, which is just additional code for you to maintain.
App::bind('params', function() {
return new Params(new HomepageRequest);
});
The final option - as mentioned in the earlier answer - is to use a realtime facade and skip the manual binding entirely. You can learn more about realtime facades in the docs.

How to integrate pimple in a custom mvc framework?

I have a basic mvc like framework, and I would like to use pimple for dependance injection, but I don't know how to use it inside the framework. This is my app structure.
x-framework
- config
- app
controller
homeController.php
- core
- vendor
pimple
lib
pimple.php
- public
Now, in homeController.php I would like to use Pimple, but without actually doing new Pimple as seen in this example.
use vendor\pimple;
class homeController
{
function index(){
$app = new Pimple();
$app['orm'] = $app->share({ return new vendor\orm; });
$orm = $app['orm'];
$orm->table('foo');
$orm->findFirst(['name'=>'john']);
}
}
It seems as seen in this example, it would be a very cumbersome task to initialize the pimple class on every controller. How is this done correctly?
My answer was not relevant, though the principle of abstract classes stays interesting. Now:
I would like to use Pimple, but without actually doing new Pimple as seen in this example.
At some point you have to instantiate an object, if you want to use it.
Pimple uses a container to store and retrieve services and parameters:
$container = new \Pimple\Container();
// define some services
$container['session_storage'] = function ($c) {
return new SessionStorage('SESSION_ID');
};
this exemple from the doc defines an anonymous function which returns a session storage object
integrating a container
Pimple, or any container, can be made available using the dependency injection pattern.
either pass it as a parameter to the index
function index(\Pimple $app){
or pass it to homeController's constructor
function __construct(\Pimple $app){
$this->app = $app;
then use it as a property or a variable
$orm = $app['orm']; // through index() parameters
$orm = $this->app['orm']; // through constructor
abstract classes allow you to define a method for every extending classes, or forcing every extending classes to define a method.
here, we define a constructor for every extending classes, typehinting the Pimple class so that php will ensure your controller receives a real pimple object
abstract class Pimpleized {
function __construct(\Pimple $pimple) {
$this->app = $pimple;
}
}
then your controller
class homeController extends Pimpleized {
function foo() {
$this->app->accessSomePimpleMethod();
}
}
that way, you only have to create your Pimple object once, then pass it to your controllers:
$pimp = new Pimple();
$controller = new homeController($pimp);
Just extend HomeController class with pimple
class HomeController extends Pimple {
public function __construct() {
$this['orm.class']= 'vendor\orm';
$this['orm'] = $this->share(function($c){ return new $c['orm.class']; });
}
}
//and use it directly just after instanciation
$controller = new HomeController();
// you can modify parameters if you need
$controller['orm.class'] = 'myothervendor\orm';
//And get class
$orm = $controller['orm'];
$orm->table('foo');
$orm->findFirst(['name'=>'john']);
i hope it's you want :) cheers

How does laravels IoC/Dependency Injector intsantiate to static instances?

So this is probably a rather simple question but I can't seems to find a very direct answer. I supposed to could keep reading the source until i figure it out but I was hoping to get a bit of understand of the process of doing so.
I understand IoC and Dependency injection, I am certainly not very experienced in either but I have a good understand of what they are trying to accomplish. So how does this Laravel instantiate to static instances? I know it uses PHP reflections but I'm still lost on the part of going from non-static to static methods. Also I know Laravel is not the only framework to implement such a design but its my preferred and most understood framework.
When you call a static method on a facade it is being handled by the magic __callStatic method on the Facade class. This method gets the underlying class that serves the facade and proxies the static call to it.
Let's look at an example facade:
<?php
class MyFacade extends Facade {
public function getFacadeAccessor() { return "MyFacade"; }
}
With this example when we make a call to the class in a static manner such as: MyFacade::doSomething() no static method exists on the class. The underlying Facade base class however contains a __callStatic method that will be called.
Facade Class Source Code
public static function __callStatic($method, $args)
{
$instance = static::resolveFacadeInstance(static::getFacadeAccessor());
switch (count($args))
{
case 0:
return $instance->$method();
// Snipped for brevity...
This method then looks up the underlying class to service the facade. If the getFacadeAccessor method on the facade returns a string then a matching entry in the application's IOC container is used (i.e. $app['MyFacade']). If we returned an object from the getFacadeAccessor method it would be used instead (i.e. public function getFacadeAccessor(){ return new MyClass(); }
Turns out that Laravel instantiate the classes under the hood! In this site, the guy makes you understanding a little more of the Laravel's core by using it to create a new facade. In the way, he explains how tit works!
It quite simple, actualy:
1 - You create a classe which extends from Laravel's Facade class with a single call like:
<?php namespace Name\Space;
use Illuminate\Support\Facades\Facade;
class MyClass extends Facade {
/**
* Get the registered name of the component.
*
* #return string
*/
protected static function getFacadeAccessor() { return 'myclass'; }
}
... that's make Laravel look for $app['myclass']. So, the ServiceProvider will bind the myclass to MyClass (according to Laravel's conventions).
2 - For that, of course, you'll have to create a Service Provider.
The Service Provider will be responsible for returning the namespace, in this case Name\Space, for the class(es) that you may want to 'turn into facades'.
3 - You'll have to register your Service Provider in the providers array in the app/config/app.php.
Now, if you look with more attention, you'll realise that what Laravel does is just import a namespace and understanding it as it was a class, as well. Under the hood, it will call a instance, but for user (programmer) it will looks like a static call.
I hope I had been clear about it! Look the link I gave to you up there and HAVE FUN! :D

ZF2: how do I get ServiceManager instance from inside the custom class

I'm having trouble figuring out how to get ServiceManager instance from inside the custom class.
Inside the controller it's easy:
$this->getServiceLocator()->get('My\CustomLogger')->log(5, 'my message');
Now, I created a few independent classes and I need to retrieve Zend\Log instance inside that class.
In zend framework v.1 I did it through static call:
Zend_Registry::get('myCustomLogger');
How can I retrieve the My\CustomLogger in ZF2?
Make your custom class implement the ServiceLocatorAwareInterface.
When you instantiate it with the ServiceManager, it will see the interface being implemented and inject itself into the class.
Your class will now have the service manager to work with during its operations.
<?php
namespace My;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorAwareTrait;
class MyClass implements ServiceLocatorAwareInterface{
use ServiceLocatorAwareTrait;
public function doSomething(){
$sl = $this->getServiceLocator();
$logger = $sl->get( 'My\CusomLogger')
}
}
// later somewhere else
$mine = $serviceManager->get( 'My\MyClass' );
//$mine now has the serviceManager with in.
Why should this work?
This works only in the context of the Zend\Mvc, which I assume you're using because you mentioned a controller.
It works because the Zend\Mvc\Service\ServiceManagerConfig adds an initializer to the ServiceManager.
$serviceManager->addInitializer(function ($instance) use ($serviceManager) {
if ($instance instanceof ServiceLocatorAwareInterface) {
$instance->setServiceLocator($serviceManager);
}
});
Give it a try and let me know what happens.

Can php have an interface inside a class?

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.

Categories