Tôi muốn thêm một phân đoạn mới (có cùng tên) vào mảng ánh xạ của mình nhưng với một phần tử khác nhau nhưng cùng một phương thức


14

Dưới đây là MapperInterface.php

Tôi đang cố gắng tìm ra cách thêm một câu lệnh if-other vào const. mảng ánh xạ. Một cái gì đó như vậy:

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;
}

Tôi hy vọng điều đó đúng. Không chắc chắn nếu có một cách tốt hơn để đi về nó nhưng cuối cùng tôi cần nhiều hơn 1 "LIN" SegId. Có thể thêm một chức năng mới và sử dụng điều kiện này?

TRẢ LỜI MỚI FILE ***

    <?php

    declare(strict_types=1);

    namespace Direct\OrderUpdate\Api;

    use Direct\OrderUpdate\Api\OrderUpdateInterface;

    /**
     * Abstract Mapper
     * Translates parsed edi file data to a \Direct\OrderUpdate\Api\OrderUpdateInterface
     * @package Direct\OrderUpdate\Api
     */

    abstract class AbstractMapper{
    // Here we add all the methods from our interface as abstract
    public abstract function getMapping(): array;
    public abstract function map(array $segments): OrderUpdateInterface;

    // The const here will behave the same as in the interface
    const CARRIER_CODES_MAPPING = ['FED' => 'fedex'];

    // We will set our default mapping - notice these are private to disable access from outside
    private const MAPPING = ['LIN' => [
    'LIN02' => 'VN',
    'LIN01' => 'processSku'],
    'PRF' => ['PRF01' => 'processIncrementId'],
    'DTM' => ['DTM02' => 'processCreatedAt'],
    'SN1' => ['SN102' => 'processQty'],
    'REF' => ['REF02' => 'processTrack']];

    private $mapToProcess = [];

    // When we initiate this class we modify our $mapping member according to our new logic
    function __construct() {
    $this->mapToProcess = self::MAPPING; // init as
    if ($this->mapToProcess['LIN']['LIN02'] == 'VN')
    $this->mapToProcess['LIN']['LIN03'] = 'processSku';
    else if ($this->mapToProcess['LIN']['LIN04'] == 'VN')
        $this->mapToProcess['LIN']['LIN05'] = 'processSku';
    }

    // We use this method to get our process and don't directly use 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 [$this->getMapping()];
    }
    public function map() : array {
        return [$this->map()];
    }

}

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

}

Vì vậy, bạn muốn mảng const MAPPING là động? bạn không thể làm điều đó với const. Bạn có thể sử dụng một chức năng khác để lấy mảng đó và sửa đổi nếu cần
dWinder

Tôi thực sự không biết bạn đang cố gắng làm gì. Bạn muốn đạt được những gì?
Stephan Vierkant

Câu trả lời:


6

Như bạn có thể thấy ở đây - biến const không thể thay đổi hoặc giữ logic . Lưu ý rằng giao diện cũng không thể giữ logic - vì vậy bạn không thể làm điều đó trong giao diện của mình.

Tôi nghĩ rằng giải pháp tốt hơn cho vấn đề của bạn là sử dụng một lớp trừu tượng . Tôi sẽ giống như giao diện của bạn (bạn có thể thấy các cuộc thảo luận về sự khác biệt ở đây nhưng tôi nghĩ nó sẽ giống nhau cho nhu cầu của bạn).

Tôi muốn giới thiệu để tạo lớp trừu tượng như thế này:

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

    // the const here will behave the same as in the interface
    const CARRIER_CODES_MAPPING = ['FED' => 'fedex'];

    // 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']['LIN03'] = 'processSku';
        else if ($this->mapToProcess['LIN']['LIN04'] == 'NV')
            $this->mapToProcess['LIN']['LIN05'] = 'processSku';
     }

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

}

Bây giờ bạn có thể khai báo đối tượng được kế thừa là:

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

Ví dụ để sử dụng là:

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

Lưu ý rằng có vẻ như logic của bạn không thay đổi nên tôi đặt biến mới và đặt nó trong quá trình xây dựng. Nếu bạn muốn, bạn có thể kết xuất nó và chỉ cần sửa đổi giá trị trả về của getProcesshàm - đặt tất cả logic ở đó.

Một lựa chọn khác là $mapToProcesscông khai và truy cập trực tiếp nhưng tôi đoán lập trình tốt hơn là sử dụng phương thức getter.

Mong rằng sẽ giúp!


Tôi sẽ có thể tích hợp / thêm toàn bộ lớp trừu tượng đó vào cùng một tệp của mình ngay bên dưới bản đồ chức năng công khai chức năng cuối cùng (mảng $ phân đoạn): OrderUpdateInterface; } TẠI ĐÂY
Singleton

Vì vậy, bây giờ tôi chỉ có thể ghi đè tất cả các mã cũ và sử dụng lớp trừu tượng này? Tôi đánh dấu câu trả lời là chính xác và rất hữu ích cho bạn của tôi. @dWinder
Singleton

Có bạn có thể. Có sự khác biệt giữa giao diện và lớp trừu tượng nhưng đối với phần lớn trường hợp nó hoạt động giống nhau (bạn có thể đọc về nó trong liên kết ở đầu bài).
dWinder

Tôi nghĩ trong logic tôi vẫn cần thêm chính xác? khác if ($ this-> mapToProcess ['LIN'] ['LIN04'] == 'VN') $ this-> mapToProcess ['LIN'] ['LIN05'] = 'processSku';
Singleton

1
Bạn nên thêm nó là tốt. Tôi chỉ đặt một số trong đó là ví dụ về nơi logic nên được. Tôi cũng sẽ chỉnh sửa nó để làm cho mã bao trùm nó
dWinder

5

Bạn không thể thêm một câu lệnh if-other bên trong định nghĩa không đổi. Gần nhất với những gì bạn đang tìm kiếm có lẽ là thế này:

const A = 1;
const B = 2;

// Value of C is somewhat "more dynamic" and depends on values of other constants
const C = self::A == 1 ? self::A + self::B : 0;

// MAPPING array inherits "more dynamic" properties of C
const MAPPING = [
    self::A,
    self::B,
    self::C,
];

Sẽ xuất:

0 => 1
1 => 2
2 => 3

Nói cách khác, bạn sẽ cần tách mảng của mình thành các hằng riêng biệt, sau đó thực hiện tất cả các định nghĩa có điều kiện, sau đó xây dựng mảng MAPPING cuối cùng từ các giá trị không đổi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.