我该如何在Magento中创建一个简单的“Hello World”模块?

311
以下如何在Magento中实现?
  • 使用控制器/视图/模型方法显示“Hello World”消息。因此,如果我访问http://example.com/myController,它将显示字符串“Hello World”。能够在我的网站模板中显示此字符串(例如标题、页脚等)将是一个奖励。

  • 如何向该控制器添加方法(或必要时新建控制器),与模型进行交互,并执行查询Select * FROM articles where id='10'并将包含列id、title、content的行返回给控制器?然后使用控制器包括一个视图,该视图将显示这一行。因此,访问http://example.com/myController/show_row(或类似的内容)将在视图中显示这一行。(无需花哨,只需要一个echo $row->id;或类似的东西即可工作。)

关于Magento的代码结构的任何其他信息也将非常有帮助。


6
系统似乎没有识别出你的赏金。 - Alana Storm
2
我现在还不能打开赏金,因为它还没到48小时。但是我会尽快打开并授予最佳答案。 - Ali
啊,我不知道赏金只适用于旧帖子,抱歉。 - Alana Storm
3
小时候,他总是对磁铁很着迷;他的代码也是同样的原理。 - vol7ron
请点击以下链接创建简单模块:https://www.rohanhapani.com/create-a-simple-module-in-magento-2/ - Rohan Hapani
5个回答

546
首先,我强烈建议您购买PHP Architect的PDF /电子书。它售价20美元,但是这是我能够找到的唯一直接了解Magento工作原理的资源。我还在自己的网站上编写Magento教程
其次,如果您有选择,并且不是经验丰富的程序员或没有经验丰富的程序员(最好是在PHP和Java中),请选择其他购物车。Magento设计得非常好,但它是为其他程序员构建模块的购物车解决方案而设计的。它并不是为那些聪明但不是程序员的人易于理解的。
第三,Magento MVC与当今PHP开发人员流行的Ruby on Rails, Django, CodeIgniter, CakePHP等MVC模型非常不同。我认为它基于Zend模型,并且整个结构非常类似于Java OOP。你需要关注的是两个控制器。一个是模块/frontName控制器,另一个是MVC控制器。
第四,Magento应用程序本身是使用您将要使用的相同模块系统构建的,因此浏览核心代码是一种有用的学习策略。此外,您将在Magento中做很多工作是覆盖现有类。我在这里介绍的是创建新功能,而不是覆盖。当您查看那里的代码示例时,请记住这一点。
我将从您的第一个问题开始,向您展示如何设置控制器/路由器以响应特定的URL。这将是一部小说。我可能稍后有时间涉及有关模型/模板的主题,但现在还没有。然而,我会简要谈一下您的SQL问题。
Magento使用EAV数据库架构。尽可能使用系统提供的模型对象来获取所需信息。我知道所有的信息都在SQL表中,但最好不要考虑使用原始SQL查询来获取数据,否则你会发疯。
最终免责声明。我使用Magento已经大约两到三周了,所以请自行判断。这是一次让我更好地理解它的练习,也是为了帮助Stack Overflow。
创建一个模块
所有对Magento的添加和定制都通过模块完成。所以,你需要做的第一件事就是创建一个新模块。在app/modules中创建一个名为以下名称的XML文件。
cd /path/to/store/app
touch etc/modules/MyCompanyName_HelloWorld.xml

<?xml version="1.0"?>
<config>
     <modules>
        <MyCompanyName_HelloWorld>
            <active>true</active>
            <codePool>local</codePool>
        </MyCompanyName_HelloWorld>
     </modules>
</config>

MyCompanyName是您修改的独特命名空间,它不必是您公司的名称,但这是Magento推荐的约定。HelloWorld是您模块的名称。

清除应用程序缓存

现在,模块文件已经就位,我们需要让Magento知道它(并检查我们的工作)。在管理应用程序中

  1. 转到“系统 -> 缓存管理”
  2. 从所有缓存菜单中选择刷新
  3. 点击保存缓存设置

现在,我们确保Magento知道该模块

  1. 转到“系统 -> 配置”
  2. 点击高级
  3. 在“禁用模块输出”设置框中,寻找名为“MyCompanyName_HelloWorld”的新模块

如果您可以忍受性能下降,您可能希望在开发/学习时关闭应用程序缓存。没有什么比忘记清除缓存并想知道为什么更改未显示更令人沮丧的了。

设置目录结构

接下来,我们需要为模块设置目录结构。您不需要所有这些目录,但现在设置它们没有任何伤害。

mkdir -p app/code/local/MyCompanyName/HelloWorld/Block
mkdir -p app/code/local/MyCompanyName/HelloWorld/controllers
mkdir -p app/code/local/MyCompanyName/HelloWorld/Model
mkdir -p app/code/local/MyCompanyName/HelloWorld/Helper
mkdir -p app/code/local/MyCompanyName/HelloWorld/etc
mkdir -p app/code/local/MyCompanyName/HelloWorld/sql

并添加一个配置文件

touch app/code/local/MyCompanyName/HelloWorld/etc/config.xml

在配置文件中添加以下内容,这基本上是一个“空白”配置。

<?xml version="1.0"?>
<config>
    <modules>
        <MyCompanyName_HelloWorld>
            <version>0.1.0</version>
        </MyCompanyName_HelloWorld>
    </modules>
</config>

简单来说,这个配置文件可以让你告诉Magento你想要运行哪些代码。

设置路由器

接下来,我们需要设置模块的路由器。这将让系统知道我们正在处理任何形式的URL。
http://example.com/magento/index.php/helloworld

因此,在您的配置文件中添加以下部分。

<config>
<!-- ... -->
    <frontend>
        <routers>
            <!-- the <helloworld> tagname appears to be arbitrary, but by
            convention is should match the frontName tag below-->
            <helloworld>
                <use>standard</use>
                <args>
                    <module>MyCompanyName_HelloWorld</module>
                    <frontName>helloworld</frontName>
                </args>
            </helloworld>
        </routers>
    </frontend>
<!-- ... -->
</config>

您说的是"任何前缀为helloworld的URL..."

http://example.com/magento/index.php/helloworld

应该使用frontName控制器MyCompanyName_HelloWorld。

因此,当您加载上面的helloworld页面时,将显示404页面,这是因为我们还没有为我们的控制器创建文件。现在让我们来做吧。

touch app/code/local/MyCompanyName/HelloWorld/controllers/IndexController.php

现在尝试加载页面。进展了!你将得到一个PHP/Magento异常,而不是404错误。
Controller file was loaded but class does not exist

因此,打开我们刚刚创建的文件,并粘贴以下代码。类的名称需要基于您在路由器中提供的名称。

<?php
class MyCompanyName_HelloWorld_IndexController extends Mage_Core_Controller_Front_Action{
    public function indexAction(){
        echo "We're echoing just to show that this is what's called, normally you'd have some kind of redirect going on here";
    }
}

我们刚刚设置的是模块/前端控制器。这是模块的默认控制器和默认操作。如果您想添加控制器或操作,您必须记住Magento URL的前三部分不可改变,它们将始终按如下方式进行: http://example.com/magento/index.php/frontName/controllerName/actionName 因此,如果您想匹配此URL
http://example.com/magento/index.php/helloworld/foo

您需要一个FooController,可以按照以下方式创建:

touch app/code/local/MyCompanyName/HelloWorld/controllers/FooController.php

<?php
class MyCompanyName_HelloWorld_FooController extends Mage_Core_Controller_Front_Action{
    public function indexAction(){
        echo 'Foo Index Action';
    }

    public function addAction(){
        echo 'Foo add Action';
    }

    public function deleteAction(){
        echo 'Foo delete Action';
    }
}

请注意,默认控制器IndexController和默认操作indexAction可以隐式使用,但如果之后有其他内容,则必须显式使用。 因此,http://example.com/magento/index.php/helloworld/foo将匹配FooController控制器和indexAction操作,而不是IndexController的fooAction操作。如果您想要一个fooAction,在IndexController控制器中,您需要像这样显式调用该控制器: http://example.com/magento/index.php/helloworld/index/foo,因为URL的第二部分始终是controllerName。 这种行为是Magento捆绑的Zend Framework的继承。 现在,您应该能够访问以下URL并查看echo语句的结果。
http://example.com/magento/index.php/helloworld/foo
http://example.com/magento/index.php/helloworld/foo/add
http://example.com/magento/index.php/helloworld/foo/delete

所以,这应该让你对Magento如何分派到控制器有一个基本的了解。从这里开始,我建议您研究现有的Magento控制器类,以了解如何使用模型和模板/布局系统。


5
谢谢,这非常有帮助。请考虑添加有关使用模型/数据库和视图的信息,以便您的答案更加完整。 - Ali
8
请确保应用程序/代码/本地/MyCompanyName/HelloWorld/etc/config.xml 与 etc/modules 中的 XML 大小写相同(MyCompanyName_HelloWorld 而不是 mycompanyname_helloworld),否则后台将出现两个条目! - Moak
8
我对Alan完美答案有一个小评论:“我们刚刚设置的是模块/前缀名控制器。这不是MVC控制器。”它与FooController完全相同类型的控制器。 在ZF中,默认情况下会调用IndexController的index action,因此请求http://example.com/magento/index.php/helloworld/将调用helloworld模块中的IndexController :: indexAction()。 因此,调用… / helloworld / foo将尝试在helloworld模块中查找FooController并在其上调用indexAction()。要触发IndexController :: fooAction(),您需要请求:… / helloworld / index / foo。 - Matus Zeman
2
请确保您阅读了@Matus Zeman的回复,以了解为什么在IndexController上找不到fooAction,这只是一个“普通”的Zend Framework MVC/router问题,而您使用了错误的URL,因此应该在您的答案中删除“This is NOT the MVC controller”部分。 - regilero
2
@hypervisor666 打开“开发者模式”(谷歌一下)。开启开发者模式后,Magento将在XML文件中出现任何错误时崩溃。 - Alana Storm
显示剩余13条评论

39

我最近一个月一直在努力解决Magento的问题,但仍在尝试中。这是盲人领瞎子的情况,因为很少有文档,而论坛/维基最多也只是混乱的。不仅如此,还有一些解决方案要么过时,要么离最佳方式相差甚远。

如果你只是想弄明白它,或者正在进行一个项目,那么修改现有功能可能比创建新内容更容易。对于这个,我肯定会使用维基中的“开发人员推荐文章”。其中的新付款方法确实让我大开眼界。

对于调试,我强烈建议使用FirePHP,并在出现问题时查看HTML源代码。老式的echo调试方法效果不太好。

总体架构是如此复杂,以至于即使我完全了解它,我也需要写一本书来涵盖它。我所能做的最好建议是,当我第一次开始时,希望有人给我一些建议...

远离核心文件。不要修改它们,而是编写自己的模块并覆盖您需要的内容。

Magento使用由XML组成的配置文件来决定它需要做什么。为了使其运行您自己的内容而不是核心功能,您需要正确的xml。不幸的是,没有关于如何构建您的XML的指南;您需要查看示例并进行一些严格的测试。为了让事情更加复杂,这些文件的内容在很大程度上是大小写敏感的。但是,如果您掌握了这些,您可以覆盖基本功能的任何部分,从而创建一个非常强大的系统。

Magento使用像Mage::getModel('mymodel')Mage::getSingleton('mysingleton')Mage::helper('myhelper')这样的方法来返回某些类的对象。默认情况下,它会在其核心命名空间中查找这些对象。如果要使用自己的类,需要在您的config.xml文件中覆盖这些内容。

您的类的名称必须对应于它们所在的文件夹。

许多Magento中的对象最终都扩展了一个称为Varien_Object的东西。这是一个通用类(有点像瑞士军刀),它的生命目的是允许您在运行时定义自己的方法/变量。例如,您将看到它被用作高级数组,以便从一种方法传递数据到另一种方法。
在开发期间,请确保禁用缓存。这会使Magento变得极其缓慢,但它会为您节省很多头痛(因为你敲打桌子)。
你会经常看到$this的使用。具体取决于您所看到的文件而意思不同。 get_class($this)是您的好友,特别是与FirePHP结合使用时。
把事情写在纸上,写很多。有无数小技巧,你会需要在遇到它们1-2天后使用它们。
Magento爱面向对象。如果跟踪一个方法需要通过5-10个不同的类,请不要感到惊讶。
阅读设计指南here。它主要是为图形设计师准备的,但是为了理解您的模块的输出将在何处和为什么结束,您需要它。不要忘记在管理面板的开发者部分打开“模板路径提示”。
还有更多,但在这里停止,以免这变成一篇专题论文。

如果您可以的话,请发布更多内容,所有信息都非常有用 :) - Ali
Misa,如果你丢失了cookie,你的所有声望都会消失,所以最好在Stackoverflow上注册。 - Ali
谢谢!这非常有帮助。Ner - Ner

3

我更倾向于推荐Mage2Gen,这可以帮助你生成样板代码,从而使你可以专注于核心业务逻辑。它只是帮助加速事情的进行。


0

Magento模块是包含块、控制器、帮助程序和模型的目录组,用于创建特定的商店功能。它是Magento平台中的自定义单元。 Magento模块可以被创建以执行多个功能,并支持逻辑以影响用户体验和商店外观。它具有生命周期,允许安装、删除或禁用它们。从商家和扩展开发人员的角度来看,模块是Magento平台的核心单元。

模块声明

我们必须使用配置文件声明模块。因为Magento 2在模块的etc目录中搜索配置模块。所以现在我们将创建配置文件module.xml。

代码如下:

<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Cloudways_Mymodule" setup_version="1.0.0"></module> </config>

模块注册 必须使用Magento组件注册器类在Magento 2系统中注册模块。现在我们将在模块根目录中创建registration.php文件:

app/code/Cloudways/Mymodule/registration.php

代码将会是这样的:

?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Cloudways_Mymodule',
__DIR__
);

检查模块状态 按照上述步骤,我们已经创建了一个简单的模块。现在,我们将使用以下命令行来检查模块的状态以及它是否已启用或禁用:

php bin/magento module:status

php bin/magento module:enable Cloudways_Mymodule

完成整个过程后,请分享您的反馈意见


0
我在尝试制作Magaplaza Hello World教程中的模块,但出了些问题。我从Github导入了该模块https://github.com/astorm/magento2-hello-world的代码,并成功运行。基于该模块,我创建了一个包含分类子类别AJAX选择下拉菜单的模块。安装到Magento2的aap/code目录后,请访问此网址http://www.example.com/hello_mvvm/hello/world。您可以从这里下载其代码https://github.com/sanaullahAhmad/Magento2_cat_subcat_ajax_select_dropdowns并将其放置在aap/code文件夹中,然后运行以下命令...
php bin/magento setup:update
php bin/magento setup:static-content:deploy -f
php bin/magento c:c

现在您可以通过以下URL检查模块功能 http://{{www.example.com}}/hello_mvvm/hello/world


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接