The vendor's code looks like this:
/**
* Create a new SendEmailsCommand instance.
*
* #param Store $store
*/
public function __construct(Store $store)
{
parent::__construct();
$this->store = $store;
}
But when I invoke this command with say php artisan mail:send, where does the value of $store come from? Is this what is meant by this cryptic documentation quote?
Note that we are able to inject any dependencies we need into the
command's constructor. The Laravel service container will
automatically inject all dependencies type-hinted in the constructor.
I see that Laravel (5.2) documentation on console commands seems to do a similar thing with an object called Drip ... https://laravel.com/docs/5.2/artisan#command-structure
Is Laravel taking upon itself to realize that there's a type-name given to the constructor, and it automagically instantiates a corresponding object instead of expecting your constructor to do so itself?
Thank you, fubar. My assumptions were correct.
Related
More specifically when doing this from inside a model.
$this->myRelationship->
I would expect at this point in typing that I should get a list of all the eloquent collection methods but I do not.
I currently have the PHP Intelephense plugin installed. What am I missing here?
Intelephense sees the myRelationship() method but doesn't see it as a property because that property is resolved in the __get magic method. What you can do is document it above the model like:
/**
* #property \Illuminate\Database\Eloquent\Collection $myRelationship
*/
class YourModel extends Model ...
and then you will have the autocomplete. Also this package can help you.
I suggest laravel-ide-helper
It can creates phpDocs automatically like below.
php artisan ide-helper:models
So your intellisense(for me: PHP Intelephense) can recognize your model's properties.
See it's Documentation for details
I am an PHP/Laravel newbie. I am working with Laravel job and everything works fine.
However, when I have a look at the implementation of dispatch method, it looks weird to me.
if (! function_exists('dispatch')) {
/**
* Dispatch a job to its appropriate handler.
*
* #param mixed $job
* #return \Illuminate\Foundation\Bus\PendingDispatch
*/
function dispatch($job)
{
return new PendingDispatch($job);
}
}
I would expect some code that enqueues the job or at least triggers something to schedule the job to be executed later on. However, the method only creates an instance of PendingDispatch and returns it. I also checked the PendingDispatch constructor and found nothing relevant.
Could anyone please help me to understand how the job is scheduled?
Whenever we dispatch a job in laravel, i call the helper that you have mentioned in question, afterwards PendingDispatch($job) is called where job is assigned in constructor, if you can look at the destructor in same file you will find the below code
public function __destruct()
{
app(Dispatcher::class)->dispatch($this->job);
}
This method, when called, will resolve an instance of Dispatcher from the container and call the dispatch() method on it. A __destruct() is a PHP magic method that's called when all references to the object no longer exist or when the script terminates, and since we don't store a reference to the PendingDispatch instance anywhere the __destruct method will be called immediately
I did'nt found any method in phpStorm to go to function definition while class I'm using is a contract, and the class i want to go to is bind behind the scenes thru laravel IOC container. How to tell PhpStorm that definition is in other folder? Interface and class implementing interface have the same names.
You can use type hinting for PHPStorm this way:
/** #var \App\Class\ConcreteObject $object */
$object= App::make(\App\Contracts\SomeContract::class);
Now PhpStorm will know $object is \App\Class\ConcreteObject object and you will be able to see all the methods from this object when using PhpStorm
EDIT
Looking at sample from comment you should use:
/** #var \proj\Repositories\definitions\UsersRepository $object */
$object= App::make(\proj\Repositories\contracts\UsersRepository::class);
$object->saveInfo();
to make PhpStorm go to valid saveInfo method
I'm building an api and I need to validate the key from within a middleware, so I want to call the router like this:
$this->getRouter()->input('key')
How would you go about this?
I also want to pass some results to the controller, so that I don't have to process the key again.
Assuming you're wanting to get the input as you say, the middleware already has the $request variable passed to it. You can simply call the key from the Request object given.
public function handle($request, Closure $next)
{
$key = $request->get('key');
...
If you're asking for the specifics of the route it's applied on you may need to rethink your strategy of what middleware does what. If you just wanted to massage the data and other various things for a specific controller then you may want to look into this being done on the controller constructor. If many controllers need it create a subcontroller of the parent controller that handles the key manipulation. Middleware as far as I know isn't meant to really handle business logic.
If this answer helped you out please mark it as so.
I am not sure if I am going about this the right way but here is what I am attempting to do, if there is a better way please let me know.
I am using a service provider that pulls some data from a config file. the problem is that if I use Config::set to change one of the settings after calling a function that uses that service provider it will not update. I thought that because I am using app->bind instead of app->share that it would re instantiate the class every time. here is my code:
service provider:
public function Register() {
$app = $this->app;
$app->bind('\path\to\MyInterface', function() use($app) {
$server = $app['config']->get('myconfig.server');
$client = $app['config']->get('myconfig.client');
$key = $app['config']->get('myconfig.key');
$version = $app['config']->get('myconfig.version');
return new MyService(new Instance($server, $client, $key, $version));
});
$this->app->booting(function() {
$loader = \Illuminate\Foundation\AliasLoader::getInstance();
$loader->alias('MyServiceFacade', '\path\to\MyFacade');
});
}
Facade class:
class MyServiceFacade extends Facade {
protected static function getFacadeAccessor() { return '\path\to\MyInterface'; }
}
route for testing:
Route::get('test', function() {
$nodes = MyServiceFacade::allNodes();
\Config::set('myconfig.server', 'new server name');
$nodes2 = MyServiceFacade::allNodes();
var_dump($nodes->getContent());
var_dump($nodes2->getContent());
}
);
I am getting the same results from both. shouldn't this be using the update config since I am making a new instance of the controller?
Skip to update 2 below for a stab at the answer
Your question doesn't quite make sense. In your testing route you're saying
App::make('MyController');
This is you asking Laravel to make an instance of the MyController service and/or class. However, you never define a MyController service and/or class.
You bind a \pathto\Interface identifier here
$app->bind('\pathto\Interface', ...
and alias MyService to that identifier here
$loader->alias('MyService', '\pathto\Facade');
but there's no place you bind or alias a MyController identifier anywhere. There's nothing in your code samples that tie MyController to the service you have bound.
Because of that it's not 100% clear what you're asking.
Update: Your question still doesn't quite make sense, and I think this not-sense-masking is what's leading the the unexpected behavior. i.e., you're doing something that "works", as in PHP doesn't complain with an error, but what you think is happening behind the scenes is not happening.
You've refereed to MyService as a facade -- however, you haven't told us what the "facade accessor" string the MyService facade points to (via its getFacadeAccessor method). Also, you appear to be directly instantiating a class from that facade class (new MyService), which isn't how Laravel facades work.
Update 2: The code samples provided are still a little sketchy, and I suspect they don't accurately reflect the actual application. The context from the comments are that MyServiceFacade::allNodes is a call to a facade. However, the facade defined in the code samples is named MyFacade and there's no class MyServiceFacade. I'm going to take a stab based on something mentioned in a comment as to the problem, but based on what I've seen above the problem still might be an incorrect application of service providers, services, and facades.
Binding a service with bind ensures the application container will always return a new instance of the service. I bet if you tried something like the following
$app = app();
$object = $app['\path\to\MyInterface'];
You'd find your object is instantiated anew every time. Adding some basic var_dump debugging to the bound closure and/or service class constructor is a good way to confirm that.
However, Laravel facades are a little different. They're not, technically, a part of the application container system. Facades are a second system built on top of the application container.
In addition to providing a convenient alias for accessing a service class, the facade implementation also forces the service object into a single-instance/singleton irrespective of how you've bound it into the container. This happens in the base facade class here
#File: vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
protected static function resolveFacadeInstance($name)
{
if (is_object($name)) return $name;
if (isset(static::$resolvedInstance[$name]))
{
return static::$resolvedInstance[$name];
}
return static::$resolvedInstance[$name] = static::$app[$name];
}
The base facade class keeps an instance cache in static::$resolvedInstance. The specifics of how Laravel gets here are a bit long for a StackExchange answer, but my Unraveling Laravel Facades article (part of a longer series) is a good place to start.
The problem here (again, based on the incomplete information provided) appears to be a misunderstanding of facades. The main takeaway is a facade always forces a service object to be a singleton.