简体   繁体   中英

PHP - Access a parent's private variable within a chaining method

I am venturing into creating custom Classes and Services within my Laravel application.

At the moment I am creating a service to store files in my Storage, however I would like to return the data in a specific format and I am not getting it.

These are my classes:

<?php

namespace App\Services\Storage;

use Ramsey\Uuid\Uuid;

class StorageService
{
    private $context;

    private $file;

    private $fileName;

    public static function context($context)
    {
        return new StorageService($context);
    }

    private function __construct($context)
    {
        $this->context = $context;
    }

    public function store($file)
    {
        $this->file = $file;

        $this->fileName = (string)Uuid::uuid4();

        // Functions to store the file
        
        return new FileData($this);
    }
}

This class is called right after the file is saved, and it basically serves to return data related to the file:

<?php

namespace App\Services\Storage;

class FileData
{
    private $file;

    public function __construct($storage)
    {
        $this->file = $storage;
    }

    public function getContext()
    {
        return $this->file->context;
    }

    public function getName()
    {
        return $this->file->fileName;
    }

    public function getDataAsArray()
    {
        return [
            'context' => $this->getContext(),
            'name' => $this->getName()
        ];
    }
}

I would like to save a file and return its data as follows:

$file = StorageService::context('support')
            ->store($request->file('file'))
            ->getDataAsArray();

Model::create($file);

With the above method I am getting the following error:

Cannot access private property App\Services\Storage\StorageService::$context

class: "App\Services\Storage\FileData"
file: "/app/Services/Storage/FileData.php"
function: "getContext"

I cannot declare the variables public as I do not want this to happen:

StorageService::context('support')->context;

Is there any other way to pass data from StorageService::class to FileData::class without having to pass all variables individually in __construct () ?

Thanks

Your are passing around objects correctly. The only thing is that PHP cannot give you access to the private properties which you defined in the Storage service.

You have 2 options:

  1. Create dedicated getter functions for specific properties, eg getFileName() and inside return the value of the private property
  2. Define a magic __get method in which you check if the requested property exists and if so you return it's value

Both these options are inside your StorageServer. With the first option you need to edit your code in the FileData file to access functions instead of properties. With the second option PHP magically takes care of that.

You can not retrieve private property from another object. add following method in the StorageService class

public function getContext()
{
    return $this->context;
}

and in FileData class change method getContext() to

public function getContext()
{
    return $this->file->getContext();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM