Laravel选择命令数字键



我正在尝试使用Laravel/Symfony提供的"选择"功能,作为控制台的一部分,当涉及到数字索引时出现问题。

我试图模拟HTML选择元素的行为,在某种意义上,你显示字符串值,但实际上得到一个相关的ID,而不是字符串。

示例-不幸的是,$choice总是名称,但我想要ID

<?php
namespace AppConsoleCommands;
use AppUser;
use IlluminateConsoleCommand;
class DoSomethingCommand extends Command
{
    protected $signature = 'company:dosomething';
    public function __construct()
    {
        parent::__construct();
    }
    public function handle()
    {
        $choice = $this->choice("Choose person", [
            1    =>    'Dave',
            2    =>    'John',
            3    =>    'Roy'
        ]);
    }
}

解决方案-如果我前缀的人ID然后它的工作,但希望有另一种方式,或者这只是一个图书馆的限制?

<?php
namespace AppConsoleCommands;
use AppUser;
use IlluminateConsoleCommand;
class DoSomethingCommand extends Command
{
    protected $signature = 'company:dosomething';
    public function __construct()
    {
        parent::__construct();
    }
    public function handle()
    {
        $choice = $this->choice("Choose person", [
            "partner-1"    =>    'Dave',
            "partner-2"    =>    'John',
            "partner-3"    =>    'Roy'
        ]);
    }
}

这可能是最好的选择,也可能不是,但如果你正在做一些非常简单的事情,那么:

$options = [
    1 => 'Dave',
    2 => 'John',
    3 => 'Roy',
];
$choice = array_search(
    $this->choice('Choose person', $options),
    $options
);

我也有过同样的问题。我将实体作为选项列出,将id作为键,将标签作为值。我原以为这是非常常见的情况,所以很惊讶地发现没有太多关于此限制的信息。

问题是控制台将根据$choices数组是否是关联数组来决定是否使用键作为值。它通过检查选择数组中是否至少有一个字符串键来确定这一点——因此抛出一个虚假的选择是一种策略。

$choices = [
  1 => 'Dave',
  2 => 'John',
  3 => 'Roy',
  '_' => 'bogus'
];

注意:你不能将键强制转换为string(即使用"1"而不是1),因为PHP在用作数组键时总是将int的字符串表示形式强制转换为true int。


我所采用的工作是扩展ChoiceQuestion类并向其添加属性$useKeyAsValue,以强制将键用作值,然后覆盖ChoiceQuestion::isAssoc()方法以尊重此属性。

class ChoiceQuestion extends SymfonyComponentConsoleQuestionChoiceQuestion
{
    /**
     * @var bool|null
     */
    private $useKeyAsValue;
    public function __construct($question, array $choices, $useKeyAsValue = null, $default = null)
    {
        $this->useKeyAsValue = $useKeyAsValue;
        parent::__construct($question, $choices, $default);
    }
    protected function isAssoc($array)
    {
        return $this->useKeyAsValue !== null ? (bool)$this->useKeyAsValue : parent::isAssoc($array);
    }
}

这个解决方案有点冒险。它假定Question::isAssoc()只用于确定如何处理选择数组。

我也有同样的问题。在图书馆里似乎没有这样的选择。我通过将索引或id与数组中的值连接来解决这个问题。例如

$choices = [
    1 => 'Dave-1',
    2 => 'John-2',
    3 => 'Roy-3'
];
$choice = $this->choice('Choose',$choices);

然后得到'-'后面的部分,如

$id = substr( strrchr($choice, '-'), 1);;

其他答案都是正确的。问题是没有基于参数的控制->ask()函数是返回数组的索引还是返回值。

但是一个简单的方法是使用chr()函数在字母和数字之间进行转换…比如
$choices[chr($i + 97)] = "this is actually option number $i";
$choice_mapper[chr($i + 97] = $what_you_really_want[$i];
\later
$choice_letter = $this->choice('Choose',$choices);
$what_i_really_wanted = $choice_mapper[$choice_letter];

HTH,

《金融时报》

最新更新