关于接口实现使用的参数验证的奇怪问题
Weird issue with parameter validation on usage of interface implementation
所以基本上我不确定这是否是解析我的代码的 PhpStorm 问题,或者它是否是 PHP 和接口的怪癖但基本上我有以下接口
<?php
namespace App\Contracts;
/**
* Interface IFileSource
* @package App\Contracts
*/
interface IFileSource
{
public function getFilesByPattern(string $filePattern) : array;
}
使用以下实现
<?php
namespace App\Sources;
use App\Contracts\IFileService;
use App\Services\File\FileService;
/**
* Class FileSource
* @package App\Sources
*/
class FileSource implements IFileSource
{
/**
* @var FileService
*/
private $fileService;
public function __construct (IFileService $fileService)
{
$this->fileService = $fileService;
}
/**
* @param string $filePattern
* @return File[]
* NOTE THIS ASSUMES FILESYSTEM
*/
public function getFilesByPattern (string $filePattern) : array
{
$filesDetails = $this->fileService->getFilesByPattern($filePattern);
return [];
}
}
和用法
<?php
namespace App\Console\Commands;
use App\Contracts\IFileSource;
use App\Sources\FileSource;
class ImportXML extends Command
{
/**
* @var FileSource
*/
protected $fileSource;
public function __construct (IFileSource $fileSource)
{
parent::__construct();
$this->fileSource = $fileSource;
}
public function handle () : void
{
$filePattern = 'APATTERN';
$files = $this->fileSource->getFilesByPattern($filePattern)
}
}
我的问题与此实现的用法有关。
所以下面是一个有效的用法:
$filePattern = 'APATTERN';
$this->fileSource->getFilesByPattern(filePattern)
但出于某种原因,以下也被视为有效用法?
$filePattern = 'APATTERN';
$this->fileSource->getFilesByPattern(filePattern,filePattern,filePattern,filePattern,filePattern,filePattern,filePattern)
为什么不在乎我不符合我的实施?
Why does it not care that i am not conforming to my implementation
这就是接口的全部意义所在——它们不关心实现。他们只关心方法是如何定义的,signature是否符合接口。
但是,我认为这里要问的真正问题是为什么 PHP 解释器 在将多个参数传递给函数时不抛出异常。答案是因为这就是 PHP 实现重载的方式。它们允许传递可变数量的参数,您可以使用 func_get_args
.
等函数访问这些参数
您绝对应该阅读 https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list 并查看新的(大概)splat 运算符 ...
。
类似的问答
- How to pass variable number of arguments to a PHP function
- https://softwareengineering.stackexchange.com/questions/165467/why-php-doesnt-support-function-overloading
所以万一其他人偶然发现了这个,
感谢 LazyOne 帮助解释我做错了什么
这是因为我在 PHPdoc 中强制执行实现,而不是依赖接口来强制执行类型提示(或将接口添加为类型提示而不是实现),一旦我更改了它果然开始抱怨了。
当接口的重点是执行这些事情时,为什么要执行一个实现。
杜
所以基本上我不确定这是否是解析我的代码的 PhpStorm 问题,或者它是否是 PHP 和接口的怪癖但基本上我有以下接口
<?php
namespace App\Contracts;
/**
* Interface IFileSource
* @package App\Contracts
*/
interface IFileSource
{
public function getFilesByPattern(string $filePattern) : array;
}
使用以下实现
<?php
namespace App\Sources;
use App\Contracts\IFileService;
use App\Services\File\FileService;
/**
* Class FileSource
* @package App\Sources
*/
class FileSource implements IFileSource
{
/**
* @var FileService
*/
private $fileService;
public function __construct (IFileService $fileService)
{
$this->fileService = $fileService;
}
/**
* @param string $filePattern
* @return File[]
* NOTE THIS ASSUMES FILESYSTEM
*/
public function getFilesByPattern (string $filePattern) : array
{
$filesDetails = $this->fileService->getFilesByPattern($filePattern);
return [];
}
}
和用法
<?php
namespace App\Console\Commands;
use App\Contracts\IFileSource;
use App\Sources\FileSource;
class ImportXML extends Command
{
/**
* @var FileSource
*/
protected $fileSource;
public function __construct (IFileSource $fileSource)
{
parent::__construct();
$this->fileSource = $fileSource;
}
public function handle () : void
{
$filePattern = 'APATTERN';
$files = $this->fileSource->getFilesByPattern($filePattern)
}
}
我的问题与此实现的用法有关。
所以下面是一个有效的用法:
$filePattern = 'APATTERN';
$this->fileSource->getFilesByPattern(filePattern)
但出于某种原因,以下也被视为有效用法?
$filePattern = 'APATTERN';
$this->fileSource->getFilesByPattern(filePattern,filePattern,filePattern,filePattern,filePattern,filePattern,filePattern)
为什么不在乎我不符合我的实施?
Why does it not care that i am not conforming to my implementation
这就是接口的全部意义所在——它们不关心实现。他们只关心方法是如何定义的,signature是否符合接口。
但是,我认为这里要问的真正问题是为什么 PHP 解释器 在将多个参数传递给函数时不抛出异常。答案是因为这就是 PHP 实现重载的方式。它们允许传递可变数量的参数,您可以使用 func_get_args
.
您绝对应该阅读 https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list 并查看新的(大概)splat 运算符 ...
。
类似的问答
- How to pass variable number of arguments to a PHP function
- https://softwareengineering.stackexchange.com/questions/165467/why-php-doesnt-support-function-overloading
所以万一其他人偶然发现了这个,
感谢 LazyOne 帮助解释我做错了什么
这是因为我在 PHPdoc 中强制执行实现,而不是依赖接口来强制执行类型提示(或将接口添加为类型提示而不是实现),一旦我更改了它果然开始抱怨了。
当接口的重点是执行这些事情时,为什么要执行一个实现。
杜