php - Laravel Service Provider - Get a class instance from an intermediate method in a method chain
Get the solution ↓↓↓I was wondering if you could help me with the following question. First of all, I would like to tell you that if I am asking this question here, it is because I have already tried many options and none have worked for me. It turns out that I am developing a package with Laravel and I am using Laravel's dependency injection. But I am at a crossroads from which I have not found a way out. I'm trying to get the instance of a class in an intermediate method from a method chain, let me explain. Here is the code very similar to what I have:
PackageServiceProvider.php
<?php
class PackageServiceProvider extends ServiceProvider
{
public function register()
{
$this->configureBindings();
}
private function configureBindings()
{
$this->app->when(A_Class::class)->needs(B_Interface::class)->give(function () {
return new B_Class();
});
}
...
A_Class.php
<?php
class A_Class implements A_Interface
{
private $b_interface;
public function __construct(B_Interface $b_interface)
{
$this->b_interface = $b_interface;
}
public function create($arg1, $arg2)
{
return $this->b_interface->method_1()->call_another_method_from_another_class();
}
}
A_Interface.php
<?php
interface A_Interface extends Arrayable, Rendereable
{
public function create($arg1, $arg2);
...
}
<?php
class B_Class implements B_Interface
{
public function __construct()
{
// Here is the question...
// How could I get here the instance of the class A_Class?
}
public function method_1()
{
// should return another class instance
}
public function method_2()
{
// should return another class instance
}
}
B_Interface.php
<?php
interface B_Interface
{
public function method_1();
public function method_2();
...
}
If you look at classB_Class``, in the
__constructmethod I'm trying to get the instance of class
A_Class``` from where that class is being called. I have tried the following:
class B_Class implements B_Interface
{
public function __construct(A_Interface $a_interface)
{
// Here is the question...
// How could I get here the instance of the class A_Class?
}
But I get the following error:
Segmentation fault
I guess there must be some way I can achieve what I need. I would appreciate any help in advance.
Answer
Solution:
Because you are referring to class A inside your class B constructor, and class B in your class A constructor, you have introduced a cyclic dependency.
This will resolve to the error you are experiencing, which is the segmentation fault, as outlined here: https://laravel.io/forum/11-08-2016-circular-dependency-causes-segmentation-fault-error-when-running-php-artisan-optimize
So the answer is to remove the cyclic dependency if possible, as you can have methods from A calling B that calls A for infinity at runtime, and you will get the above error above again.
If your class A and B are relatively small, I would recommend combining them before using a cyclic dependency.
For interest and prosperity, if you want achieve a cyclic dependency, this is possible by registering your Class A with a singleton from inside A's constructor, and putting the reference to the incomplete object into Class B with your code above. I try with laravels singleton here, its untested, but hopefully you'll get the idea.
class A_Class implements A_Interface
{
public function __construct(B_Interface $b_interface)
{
//I dont think you can pass $this to a function when construction is incomplete, hence $that.
$that = $this;
App::singleton('A_Class', function($that){
return $that;
});
$this->b_interface = $b_interface;
}
}
class B_Class implements B_Interface
{
public function __construct(A_Interface $a_interface)
{
//unfinished object, but no more error.
$this->aClass = App::make('A_Class')
}
}
Share solution ↓
Additional Information:
Link To Answer People are also looking for solutions of the problem: script cache:clear returned with error code 255
Didn't find the answer?
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.