Instantiating Helper di Magento 2

26

Bangunan Magento 2 terbaru telah dihapuskan dengan Magekelas. Ini berarti kami kehilangan Mage::helpermetodenya.

Apakah ada teknik pengganti (pabrik pembantu?) Untuk membuat instantiating pembantu di Magento 2? Atau apakah kita diharapkan untuk menggunakan kelas manajer objek baru, dan hanya instantiate helper sebagai objek tunggal / cache dengan get(vs. create)

Alan Storm
sumber

Jawaban:

31

Saya melihat Anda datang ke solusi yang tepat, hanya ingin meringkas.

Injeksi konstruktor harus digunakan untuk mengambil helper (atau contoh lain) di kelas apa pun yang Anda butuhkan:

class SomeClass
{
    public function __construct(\Magento\Core\Helper\Data $helper)
    {
        $this->helper = $helper;
    }

    public function doSmth()
    {
        $this->helper->someMethod();
    }
}

Perhatikan bahwa tidak ada komentar phpDoc yang diperlukan , Magento akan membaca tanda tangan konstruktor secara langsung untuk mengetahui dependensi apa yang diperlukan.

\ Magento \ Core \ Helper \ Factory harus digunakan hanya dalam kasus-kasus langka ketika Anda harus memanggil banyak pembantu, atau Anda tidak tahu persis mana yang Anda butuhkan.

Penggunaan Object Manager secara langsung sangat tidak disarankan . Jadi tolong hindari menggunakan:

\Magento\Core\Model\ObjectManager::getInstance()

Itu ada di sana hanya untuk serialisasi / deserialization.

Anton Kril
sumber
jangan gunakan statis karena tidak dapat diuji dengan unit PHP dan ya itu tidak disarankan. Semua dependensi M2 dilakukan melalui konstruktor, dan dikelola oleh Object Manager secara internal, dan akan mengambilnya sebagai Singleton Juga tidak menggunakan _ untuk menunjukkan visibilitas properti, Semua penamaan M2 harus menggunakan camecase
PartySoft
@Anton Kril jika kita gunakan helperdalam template, seperti $this->helper('Magento\Catalog\Helper\Image'), ini mengikuti praktik terbaik?
Khoa TruongDinh
2
Tidak. Template seharusnya hanya mereferensikan blok. Pembantu harus dihindari
Anton Kril
10

Sepertinya orang-orang yang mendorong Magento untuk menggunakan sistem injeksi ketergantungan otomatis baru mereka untuk mendapatkan pembantu dan model ke objek melalui konstruktor objek.

Versi singkatnya? Jika Anda memiliki objek yang dibuat oleh manajer objek, dan menghiasi konstruktor dengan PHPDoc@param , dan parameter memiliki set petunjuk jenis yang tepat, manajer objek akan secara otomatis instantiate helper (atau, saya percaya, objek lain) untuk Anda.

Misalnya, konstruktor berikut akan menyuntikkan pembantu data inti ke objek.

/**
* @param \Magento\Core\Helper\Data $coreData
*/        
public function __construct(\Magento\Core\Helper\Data $coreData)
{
    $this->_coreHelper = $coreData;            
}
Alan Storm
sumber
Ini adalah jawaban yang benar - sulap hebat; tidak sepenuhnya jelas bagi saya bahkan setelah banyak menggali.
philwinkle
2
OKE ... sekarang kepalaku sakit ... banyak. Maksudmu kita seharusnya menggunakan PHPDoc untuk "menulis" kode? Ini adalah kegilaan. Saya keluar.
Marius
@Marius hahaha ini tidak biasa - Blog Alan menjelaskannya sampai batas tertentu.
philwinkle
3
@ philwinkle. Saya sudah membaca artikelnya. Sangat menarik, tetapi saya masih mengatakan ini gila. Panggil saya kuno, tetapi "kembali ke masa saya" kode adalah kode dan komentar adalah hal-hal yang hampir tidak ada yang mau menulis.
Marius
Oh ... dan omong-omong. +1. Pertanyaan bagus & jawaban yang bagus.
Marius
7

Terlepas dari semua jawaban di atas, jika Anda harus menggunakan helper dalam templat phtml, Anda dapat melakukannya seperti ini:

$this->helper('[Vendor]\[Module]\Helper\[Helper Name]');

Saya harap ini membantu jika seseorang tidak mengetahuinya sebelumnya;)

rbncha
sumber
6

Cara helper dibuat instantiated (setidaknya untuk modul Backend (~ dev50) baru) adalah melalui helperFactory:

/**
 * Return helper object
 *
 * @param string $name
 * @return \Magento\Core\Helper\AbstractHelper
 */
public function helper($name)
{
    return $this->_helperFactory->get($name);
}

Yang pada dasarnya hanyalah tipe khusus dari pabrik model. Contoh: Magento \ Core \ Block \ Context line 143 (dev50) sebagai bagian dari konstruktor:

\Magento\Core\Model\Factory\Helper $helperFactory

Pabrik helper akan mengembalikan model yang diminta berdasarkan nama kelas dan memastikan bahwa itu adalah instanceofkelas abstrak helper:

/**
 * Get helper singleton
 *
 * @param string $className
 * @param array $arguments
 * @return \Magento\Core\Helper\AbstractHelper
 * @throws \LogicException
 */
public function get($className, array $arguments = array())
{
    $className = str_replace('_', '\\', $className);
    /* Default helper class for a module */
    if (strpos($className, '\Helper\\') === false) {
        $className .= '\Helper\Data';
    }

    $helper = $this->_objectManager->get($className, $arguments);

    if (false === ($helper instanceof \Magento\Core\Helper\AbstractHelper)) {
        throw new \LogicException(
            $className . ' doesn\'t extends Magento\App\Helper'
        );
    }

    return $helper;
}

Jika Anda mengimplementasikannya sendiri , sepertinya inti Magento memuatnya dengan salah satu dari dua cara berikut:

Gulung pabrik Anda sendiri:

$objectManager = \Magento\Core\Model\ObjectManager::getInstance();

$helperFactory = $objectManager->get('\Magento\Core\Model\Factory\Helper');
$helper = $helperFactory->get('\PulseStorm\Commercebug\Helper\Data');

Atau langsung ambil:

$helper = \Magento\Core\Model\ObjectManager::getInstance()->get('Magento\Core\Helper\Data');
Philwinkle
sumber
1
+1 untuk informasi yang bermanfaat, tetapi apakah Anda ingin membuat instantiate pabrik langsung seperti itu? Atau haruskah pabrik pembantu tunggal dipakai dengan Object Manager sebagai kelas cache dengan get?
Alan Storm
Tidak sepenuhnya jelas, karena pabrik pembantu diwariskan dari \ Mage \ Core \ Block \ Abstract - Saya pikir niatnya adalah menyediakan pabrik pembantu Anda sendiri. Itu tidak terlihat seperti mereka sengaja menciptakan tunggal untuk pabrik, meskipun.
philwinkle
Kedengarannya seperti yang saya butuhkan / sumber terbaik adalah untuk melacak bagaimana _helperFactory disuntikkan ke objek-objek itu dan melihat bagaimana tim inti membuat instance.
Alan Storm
Ringkasan penyederhanaan saya salah dan konstruktor memerlukan instance ObjectManager. Saya akan mengedit sebentar.
philwinkle
Lihat edit. Itu harus bekerja - sulit untuk menentukan pada saat ini karena lingkungan cli shell saya tidak memuat contoh konfigurasi store seperti yang diharapkan. Ini seharusnya cukup untuk membuat Anda di jalur yang benar.
philwinkle
0

Coba dengan cara ini

$helper = \Magento\Framework\App\ObjectManager::getInstance()->get('Xx\Xx\Helper\Xx');
Thushan
sumber
Penggunaan Object Manager secara langsung sangat tidak disarankan.
sv3n
@ sv3n bisa tolong jelaskan, apa alasannya ?. Terima kasih.
Thushan
1
Sebaiknya gunakan suntikan ketergantungan ... jawab di sini misalnya ... magento.stackexchange.com/questions/142352/…
sv3n