我想将新的segmentId(具有相同的名称)添加到我的映射数组中,但具有不同的elementId但方法相同

问题描述 投票:3回答:2

下面是MapperInterface.php

我试图弄清楚如何在const中添加if-else语句。映射数组。像这样:

if (LIN02 == “VN”) 
o   Treat LIN03 as the SKU
·         else if (LIN04 == “VN”) 
o   Treat LIN05 as the SKU

<?php

declare(strict_types=1);

namespace Direct\OrderUpdate\Api;

use Direct\OrderUpdate\Api\OrderUpdateInterface;

/**
 * Interface MapperInterface
 * Translates parsed edi file data to a \Direct\OrderUpdate\Api\OrderUpdateInterface
 * @package Direct\OrderUpdate\Api
 */
interface MapperInterface
{
    /**
     * Mapping array formatted as MAPPING[segemntId][elemntId] => methodNameToProcessTheValueOfElement
     * @var array
     */
    const MAPPING = [
        'DTM' => ['DTM02' => 'processCreatedAt'],   // shipment.created_at
        'PRF' => ['PRF01' => 'processIncrementId'], // order.increment_id
        'LIN' => ['LIN05' => 'processSku'],         // shipment.items.sku
        'SN1' => ['SN102' => 'processQty'],         // shipment.items.qty
        'REF' => ['REF02' => 'processTrack']        // shipment.tracks.track_number, shipment.tracks.carrier_code
    ];

    /**
     * Mapping for carrier codes
     * @var array
     */
    const CARRIER_CODES_MAPPING = ['FED' => 'fedex'];

    /**
     * @return array
     */
    public function getMapping(): array;

    /**
     * @param array $segments
     * @return OrderUpdateInterface
     */
    public function map(array $segments): OrderUpdateInterface;
}

我希望这是有道理的。不知道是否有更好的方法可以解决此问题,但最终我需要多个“ LIN” segmentId。也许添加一个新功能并使用这种条件?

php arrays mapping const
2个回答
0
投票

您的方法没有意义,因为:

  1. 常量具有不可更改的永久值;
  2. 常量不能有任何条件;
  3. 与普通变量完全相同的常量不能包含任何逻辑;
  4. 您尝试进行的逻辑与具体实现有关,与接口无关。该接口只能描述客户端类和实现此接口的类之间的协定,并且不包含任何实现细节。

嗯,您有两种方法可以解决此任务:

  1. 您可以实现将包含所有必要逻辑的方法;
  2. 您可以创建将实现所有必要逻辑的地图的单独类

0
投票

如您所见,here-const变量不能更改或保持逻辑。

请注意,该接口无法保存逻辑-因此您可以在接口中进行操作。

我认为针对您的问题的更好解决方案是使用abstract class。我将与您的界面相同(您可以看到有关不同的here的讨论,但我认为对于您的需求它将是相同的)。

我建议以此方式创建抽象类:

abstract class AbstractMapper{
    // here add all the method from your interface as abstract
    public abstract function getMapping(): array;

    // set your default mapping - notice those are private to disable access from outside
    private const MAPPING = ['LIN' => ['LIN02' => 'NV', 'LIN01' => 'processSku'], 'PRF' => ['PRF01' => 'processIncrementId']];
    private $mapToProcess = [];

    // when initiate this class modify your $mapping member according your logic
    function __construct() {
        $this->mapToProcess = self::MAPPING; // init as 
        if ($this->mapToProcess['LIN']['LIN02'] == 'NV')
            $this->mapToProcess['LIN']['LIN04'] = 'processSku';
    }

    // use method to get your process and don't use directly the map
    public function getProcess($segemntId, $elemntId) {
        return $this->mapToProcess[$segemntId][$elemntId];
    }

}

现在您可以声明继承为的对象:

class Obj extends AbstractMapper {
    // notice that as interface it need to implement all the abstract methods
    public function getMapping() : array {
        return [];
    }
}

使用示例为:

$obj  = New Obj();
print_r($obj->getProcess('LIN', 'LIN01'));

希望有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.