Laravel 未定义 属性 当 属性 存在于 parent class 中时出错

Laravel Undefined property error when property exists in parent class

另外两个类似的问题要求 Properties not to be Private () and a call to the Parent Constructor (Undefined property when accessing properties from a parent class),这些不是我的问题。

我有一个继承的 class,即 Object 实例,但我正在调用 parent 提供的函数,该函数访问它自己的受保护 属性 .
在一个 object 中,代码确实有效,除非我进行单独的函数调用(参见下面的代码),在这种情况下,我会收到此错误,在另一个 class 中,我会在 运行 时收到错误sendExport() 即使没有额外的行来强制出现问题(错误嵌入在已损坏的返回 Excel 中)。

我看不出我的 child class 之间有任何区别,所以我不知道为什么行为不同,即使一个可以满足我的需要,但它可以生成一个错误让我很紧张,所以任何关于可能 issues/fix 的指示都会很棒。

错误是:

Undefined property: App\Helpers\Exports\StudyExport::$spreadsheet at ExcelReport.php:20
Line 20 is: if($this->spreadsheet instanceof Spreadsheet){

这是 Parent class ExcelReport.php,sendExport() 是要查看的函数,它调用 getExcel(),你会注意到那里不需要构造函数调用:

<?php
namespace App\Helpers;

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Illuminate\Support\Facades\Auth;

class ExcelReport 
{
    protected $cellRow=0;
    protected $count=0;
    protected $excelSec=1/24/60/60;
    protected $spreadsheet=null;

    public function checkExcel(){
        return $this->spreadsheet instanceof Spreadsheet;
    }

    public function getExcel($tab=0){
        if($this->spreadsheet instanceof Spreadsheet){
            if($tab>=$this->spreadsheet->getSheetCount()) $tab=0;
            $this->spreadsheet->setActiveSheetIndex($tab);
            $writer=new Xlsx($this->spreadsheet);
            ob_start();
            $writer->save('php://output');
            $this->spreadsheet->disconnectWorksheets();
            unset($this->spreadsheet);
            return ob_get_contents();
        }else{
            return $this->spreadsheet;
        }
    }

    public function sendExport($title,$tab=0){
        $filename=$this->filename($title,Auth::user()->dateFormat()).'.xlsx';
    
        // This line is not actually needed, without it, the code works (in one child but not in 
        // another), with it the call to getExcel() gives the error
        $this->getExcel($tab);
        // /////

        return response()->streamDownload(
            function () use ($tab) { $this->getExcel($tab);}, 
            $filename,
            [
            'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'Cache-Control' => 'max-age=0'
            ]
        );
    }


    protected function getSheet(){
        if(is_null($this->spreadsheet)) $this->spreadsheet=new Spreadsheet();
        else                            $this->spreadsheet->createSheet();
        
        $this->cellRow=$this->count=0;

        return $this->spreadsheet->setActiveSheetIndex($this->spreadsheet->getSheetCount()-1);  
    }

    protected function getCol($num){
        $letter = chr(65 + ($num % 26));
        $num2 = intval($num / 26);
        return ($num2 > 0)
            ? $this->getCol($num2 - 1) . $letter
            : $letter;
    }
    protected function toExcelTime($sec){
        return $sec*$this->excelSec;
    }
    

    private function filename($title, $format='d-m-Y'){
        $today=new \DateTime();
        $title= substr(
            str_replace(
                array_merge(
                    array_map('chr', range(0,31)),["<", ">", ":", '"', "/", "\", "|", "?", "*"]
                ),
                "_", 
                $title
            )
        ,0,100);

        return $title.' '.$today->format($format);
    }       
}

child class 代码并不真正相关,但当然它们是用 extends

定义的
use App\Helpers\ExcelReport;

class StudyExport extends ExcelReport
{
    

问题是这一行:

    unset($this->spreadsheet);

应该是:

    $this->spreadsheet = null;

这并没有解决我所有的问题,但现在让我有了一致的行为。我的新 Child class 仍然给我一个损坏的 Excel 文件,但这可能是由于 child 的代码中存在一些问题,因为它现在一直在运行所有其他人。

(感谢帮我看清自己错误的评论者)