skip to Main Content

In laravel 9 app I created class app/Implementations/LocalStorageUploadedFileManagement.php :

<?php

namespace AppImplementations;

use AppInterfacesUploadedFileManagement;
...
use InterventionImageFacadesImage as Image;

class LocalStorageUploadedFileManagement implements UploadedFileManagement
{
    ...
    public function getImageFileDetails(string $itemId, string $image = null, string $itemUploadsDirectory = '',
        bool $skipNonExistingFile = false): array {
        Log::info('++ getImageFileDetails$image ::');
        Log::info( $image );

    }
    ...

and Interface class in app/Interfaces/UploadedFileManagement.php :

<?php

namespace AppInterfaces;

use IlluminateHttpRequest;

interface UploadedFileManagement
{
    ...
    public function getImageFileDetails(string $itemId, string $image = null, string $itemUploadsDirectory = '',
        bool $skipNonExistingFile = false): array;

}

In app/Providers/AppServiceProvider.php I have:

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->bind('AppInterfacesUploadedFileManagement', 'AppImplementationsLocalStorageUploadedFileManagement');
        
    }

so I can use it in my controller app/Http/Controllers/Admin/ProductController.php:

<?php

namespace AppHttpControllersAdmin;
...
use AppInterfacesUploadedFileManagement;

class ProductController extends Controller  // http://local-mng-products.com/admin/products
{

    public function __construct()
    {
    }

    public function edit(string $productId, UploadedFileManagement $uploadedFileManagement)
    {
        ...
        $productImgProps = $uploadedFileManagement->getImageFileDetails(
            itemId : $product->_id,
            itemUploadsDirectory : Product::getUploadsProductDir(),
            image : $product->image,
            skipNonExistingFile : true);
        
        ...

abd it works ok

But I got error :

Cannot instantiate interface AppInterfacesUploadedFileManagement

when I try to use UploadedFileManagement in library app/Library/ReportProduct.php class :

<?php

namespace AppLibrary;

use AppInterfacesUploadedFileManagement;
...
class ReportProduct
{

    public function getImageProps()
    {
        $uploadedFileManagement= new UploadedFileManagement();  // This line raised the error
        $imgProps = $uploadedFileManagement->getImageFileDetails($this->product->_id, $this->product->image, Product::getUploadsProductDir(),true);
        return $imgProps;
    }

getImageProps method is called from ProductCardReport component, which I created with command :

php artisan make:component  ProductCardReport

and it has in file app/View/Components/ProductCardReport.php :

<?php

namespace AppViewComponents;

use AppLibraryReportProduct;
use IlluminateViewComponent;

class ProductCardReport extends Component
{
    public string $productId;

    public function __construct(string $productId)
    {
        $this->productId = $productId;
    }

    public function render()
    {
        $reportProduct = new ReportProduct($this->productId);
        $reportProduct->loadProduct();
        $productData = $reportProduct->getProductData(true);

        $productImgProps = $reportProduct->getImageProps();
        ...
    

Why I got error in ReportProduct.php class on using of UploadedFileManagement service?

How that can be done ?

MODIFIED BLOCK :
I tried to inject it in the same way I did in ProductController edit function.
But I failed as If I try to edit app/Library/ReportProduct.php with similar injection :

<?php

namespace AppLibrary;

use AppInterfacesUploadedFileManagement;
...

class ReportProduct
{
    public function __construct(Product | string $product, UploadedFileManagement $uploadedFileManagement = null)
    {
        $this->uploadedFileManagement = $uploadedFileManagement;
        ...

But as I create ReportProduct and call getImageProps from app/View/Components/ProductCardReport.php component
I need to UploadedFileManagement class from somewhere for the 1st time . I can not inject
UploadedFileManagement in app/View/Components/ProductCardReport.php.
Not shure how injection works here and how can I use it in chain Component->customClass?

Thanks!

2

Answers


  1. Chosen as BEST ANSWER

    Valid decision is :

    $uploadedFileManagement= app(UploadedFileManagement::class);
    $productImgProps = $uploadedFileManagement->getImageFileDetails(
        itemId : $product->_id,
        itemUploadsDirectory : Product::getUploadsProductDir(),
        image : $product->image,
        skipNonExistingFile : true);
        
    

  2. Your UploadedFileManagement is an object interface and interfaces are not instantiable (a fancy way of saying you can’t create an instance of an interface – i.e. new UploadedFileManagement()).

    Binding an interface and an implementation in the Laravel service container doesn’t magically transform your code to use the implementation wherever you have made use of the interface. All it does is tell Laravel how to resolve a dependency when it encounters one.

    To clarify this when you run your application

    $service = new UploadedFileManagement();
    

    Doesn’t get converted to

    $service = new LocalStorageUploadedFileManagement();
    

    That is not how dependency injection or the service container work.

    If you want to make use of your LocalStorageUploadedFileManagement() class in the ReportProduct class, you will need to inject it in the same way you have done with your ProductController edit function.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search