Magento开发文档(八):Varien数据收集

最早的时候,作为PHP程序员,如果你想获取一组相关的变量,最好的办法就是使用数组存储。在其它编程语言里,这个办法就显得不那么简单了。他们拥有多种数据结构可以选择,每个都在存储,速度和语法上有些区别。PHP这门语言则将这些选择统统抹掉,并且只给程序员最有用的数据结构来完成这项任务。

不过PHP5已经通过内置的类和接口,视图改变这种情况,允许程序员创建自己的数据结构。

$array = new ArrayObject();
class MyCollection extends ArrayObject{…}
$collection = new MyCollection();
$collection[] = ‘bar’;

之后这段对于译者来说有点难度,为了不误导大家,直接上英文。

While this is still galling to a certain type of software developer, as you don’t have access to low level implementation details, you do have the ability to create array-like Objects with methods that encapsulate specific functionality. You can also setup rules to offer a level of type safety by only allowing certain kinds of Objects into your Collection.

It should come as no surprise that Magento offers you a number of these Collections. In fact, every Model object that follows the Magento interfaces gets a Collection type for free. Understanding how these Collections work is a key part to being an effective Magento programmer. We’re going to take a look at Magento Collections, starting from the bottom and working our way up. Setup a controller action where you can run arbitrary code, and let’s get started.

数据收集

首先,我们实例化Varien_Object()类,创建一些新的对象。

$thing_1 = new Varien_Object();
$thing_1->setName('Richard');
$thing_1->setAge(24);

$thing_2 = new Varien_Object();
$thing_2->setName('Jane');
$thing_2->setAge(12);

$thing_3 = new Varien_Object();
$thing_3->setName('Spot');
$thing_3->setLastName('The Dog');
$thing_3->setAge(7);

所有的Magento模型都继承自Varien_Object()类。这在面向对象架构中是一个常用的设计模式,你可以轻易的添加新的方法或功能到任意一个对象,而不用修改类文件。

任何继承自Varien_Object()类的对象都拥有getter和setter魔术方法,可以方便的用来设置属性值。试下下面这段代码,

var_dump($thing_1->getName());

如果你还不晓得该获取什么属性,例如上面的getName()中的Name,也可以直接读取所有的数据到一个数组中,

var_dump($thing_3->;getData());

上面这段代码会返回类似下面的一个数组,

array
'name' => string 'Spot' (length=4)
'last_name' => string 'The Dog' (length=7)
'age' => int 7

注意下名为“last_name”的属性,如果属性名中包含有下划线,你必须以驼峰命名的方式才能使用getter和setter魔术方法调用它。

$thing_1->setLastName('Smith');

在Magento的最新版本中,你也可以使用数组的形式来读取该属性。

var_dump($thing_3["last_name"]);

获取一些对象之后,我们给他们添加收集(Collection)。收集像数组一样,但它由PHP程序员定义。

$collection_of_things = new Varien_Data_Collection();
$collection_of_things
->addItem($thing_1)
->addItem($thing_2)
->addItem($thing_3);

绝大部分Magento数据收集继承自Varien_Data_Collection()类。任何集成自该类的方法都能够使用它的方法。(我觉得这句是废话)。

数据收集可以做些什么呢?首先,我们可以使用foreach语句循环数据

foreach($collection_of_things as $thing) {
    var_dump($thing->getData());
}

还有两个方法,分别可以获取第一个和最后一个数据,

var_dump($collection_of_things->getFirstItem());
var_dump($collection_of_things->getLastItem()->getData());

当然还可以输出为XML格式~~

var_dump( $collection_of_things->toXml() );

只获取单独的一个字段,

var_dump($collection_of_things->getColumnValues('name'));

Magento团队同样提供了一些基础的过滤方法,

var_dump($collection_of_things->getItemsByColumnValue('name','Spot'));

模型收集

这些可能很有意思,但是为什么我们需要关注它呢?这是因为Magento内置的数据收集都继承自该类。也就是说,对于产品收集(或者分类收集),你可以使用同样的方法。看下下例,

public function testAction() {
    $collection_of_products = Mage::getModel('catalog/product')->getCollection();
    var_dump($collection_of_products->getFirstItem()->getData());
}

Magento模型对象多数拥有getCollection()方法,默认的,它返回系统中和该对象同类型的对象的收集。Most Magento Model objects have a method named getCollection which will return a collection that, by default, is initialized to return every Object of that type in the system.

产品收集,以及Magento中其他的收集,还同样继承自Varien_Data_Collection_Db类。该类同样提供了很多有用的方法。例如,如果你想查看某个收集使用的select查询语句,

public function testAction() {
    $collection_of_products = Mage::getModel('catalog/product')->getCollection();
    var_dump($collection_of_products->getSelect());
}

上面一段代码会输入如下内容,

object(Varien_Db_Select)[94]
protected ‘_bind’ =>
array
empty
protected ‘_adapter’ =>

因为Magento使用的是Zend的数据库抽象层,Select查询语句是个对象。让我们将其转换为字符串,

public function testAction() {
    $collection_of_products = Mage::getModel('catalog/product')->getCollection();
    var_dump((string)$collection_of_products->getSelect());
}

这段代码可能会返回一个简单的select语句,

‘SELECT `e`.* FROM `catalog_product_entity` AS `e`’

有时候也会返回更复杂的语句,

string ‘SELECT `e`.*, `price_index`.`price`, `price_index`.`final_price`, IF(`price_index`.`tier_price`, LEAST(`price_index`.`min_price`, `price_index`.`tier_price`), `price_index`.`min_price`) AS `minimal_price`, `price_index`.`min_price`, `price_index`.`max_price`, `price_index`.`tier_price` FROM `catalog_product_entity` AS `e`
INNER JOIN `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id AND price_index.website_id = ’1′ AND price_index.customer_group_id = 0′

这些不同取决于你选择的属性,还有就是前面提到过的索引和缓存。如果你看过这个系列的教程,你知道很多Magento模型使用的是EAV模型。默认情况下,EAV收集不会包含所有的对象属性。可以通过addAttributeToSelect()方法添加选取的属性。

$collection_of_products = Mage::getModel('catalog/product')
    ->getCollection()
    ->addAttributeToSelect('*');

或者,可以只添加一个属性,

$collection_of_products = Mage::getModel('catalog/product')
    ->getCollection()
    ->addAttributeToSelect('meta_title');

还可以直接以链接的方式选择多个属性

$collection_of_products = Mage::getModel('catalog/product')
    ->getCollection()
    ->addAttributeToSelect('meta_title')
    ->addAttributeToSelect('price');

数据库延迟加载

刚接触Magento ORM系统的程序员对于Magento数据库的调用问题会非常头疼。当使用纯SQL语句或者普通的ORM系统时,SQL语句会在对象实例化之后立刻被调用。

$model = new Customer();
//sql语句调用
echo 'Done'; //执行结束

Magento的运行方式于此不同,延迟加载的概念被应用于Magento数据库调用中。简单来说,延迟加载是SQL不会被立刻执行,知道客户端程序员需要调用该数据时。例如,当编写如下代码时,

$collection_of_products = Mage::getModel('catalog/product')->getCollection();

Magento实际上并未运行任何的数据库操作,你仍然可以继续添加需要select的属性,

$collection_of_products = Mage::getModel('catalog/product')-getCollection();
//其他操作
$collection_of_products->addAttributeToSelect('meta_title');

并且,Magento同样不会在添加一个新的属性之后运行任何数据库查询。即在你试图在收集中尝试读取内容之前,数据库不会进行任何查询。

过滤数据库收集

在数据库收集中最重要的方法就应该是addFieldToFilter()了。该方法将where字句添加到查询语句当中,一起看下下面的这段代码(将参数二替换为你产品中的sku)

public function testAction() {
    $collection_of_products = Mage::getModel('catalog/product')->getCollection();
    $collection_of_products->addFieldToFilter('sku', '你的产品sku');

    //除此之外,还可以将收集传递个count()函数,计算select的数目
    echo "该收集包含" . count($collection_of_products) . '个记录';
    var_dump($collection_of_products->getFirstItem()->getData());

addFieldToFilter()方法的参数一是你希望过滤的属性,参数二是该属性的值。对于参数二,还可以指定为过滤的类型。下面看下使用该方法进行的稍微复杂的过滤。

上面说过,下面这段代码,相当于数据库中的where字句“WHERE sku = ‘xxx’”

$collection_of_products->addFieldToFilter('sku', 'xxx');

不相信?哈哈,下面这段代码可以直接输出该收集的查询语句,

public function testAction() {
   var_dump( (string)
        Mage::getModel('catalog/product')->getCollection()
        ->addFieldToFilter('sku', 'xxx')->getSelect()
    );
}

输出如下,

SELECT `e`.* FROM `catalog_product_entity` AS `e` WHERE (e.sku = ‘xxx’)

必须谨记于心的是,这在使用EAV属性的时候,这些很快就会变的非常复杂,例如选择所有属性,

var_dump( (string)
    Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToSelect('*')->addFieldToFilter('sku', 'xxx')
    ->getSelect()
)

输出的将会是如下比较庞大的查询语句,

SELECT `e`.*, IF(_table_meta_title.value_id>0, _table_meta_title.value, _table_meta_title_default.value) AS `meta_title`
FROM `catalog_product_entity` AS `e`
INNER JOIN `catalog_product_entity_varchar` AS `_table_meta_title_default`
ON (_table_meta_title_default.entity_id = e.entity_id) AND (_table_meta_title_default.attribute_id=’103′)
AND _table_meta_title_default.store_id=0
LEFT JOIN `catalog_product_entity_varchar` AS `_table_meta_title`
ON (_table_meta_title.entity_id = e.entity_id) AND (_table_meta_title.attribute_id=’103′)
AND (_table_meta_title.store_id=’1′)
WHERE (IF(_table_meta_title.value_id>0, _table_meta_title.value, _table_meta_title_default.value) = ‘my title’)

addFieldToFilter()方法提供的更多查询子句

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值