【问题标题】:Laravel choice command numeric keyLaravel 选择命令数字键
【发布时间】:2016-10-03 09:37:56
【问题描述】:

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

我正在尝试模拟 HTML 选择元素的行为,即您显示字符串值但实际上返回的是关联 ID 而不是字符串。

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

<?php

namespace App\Console\Commands;

use App\User;
use Illuminate\Console\Command;

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 App\Console\Commands;

use App\User;
use Illuminate\Console\Command;

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'
        ]);
    }
}

【问题讨论】:

    标签: laravel symfony console command


    【解决方案1】:

    我也有同样的问题。我将实体列为选择,ID 作为键,标签作为值。我认为这将是极其常见的情况,因此惊讶地发现关于此限制的信息不多。

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

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

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


    我采用的解决方法是扩展ChoiceQuestion 类并向其添加一个属性$useKeyAsValue,以强制将某个键用作值,然后重写ChoiceQuestion::isAssoc() 方法以兑现这个属性。

    class ChoiceQuestion extends \Symfony\Component\Console\Question\ChoiceQuestion
    {
        /**
         * @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() 将仅用于确定如何处理选择数组。

    【讨论】:

      【解决方案2】:

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

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

      然后得到'-'之后的部分

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

          其他答案都是正确的。问题是没有基于参数的控制 ->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,

          -FT

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-11-14
            • 2018-04-22
            • 2018-03-22
            • 1970-01-01
            • 2013-03-02
            • 2019-06-10
            • 2016-12-09
            • 1970-01-01
            相关资源
            最近更新 更多