Warning: Redis::connect(): connect() failed: Connection refused in /var/www/admclub.com/wp-content/object-cache.php on line 418
扩展Magento核心静态类的方法(2) | _站长俱乐部站长俱乐部


Ive been having trouble with abstract classes too. I think I now understand the issue:

Magento generally uses the class name as the job of the class. This is partly why the config.xml seems so repetitive. The class is being identified as the implementor of the particular job. It just happens that the job name and class name start out pretty much the same in Magento.

When you rewrite a class in a config statement you are actually saying take the job of e.g. “Mage_Sales_Model_Order_Pdf_Invoice” and get my new class to do it. This is causing the confusion about abstract classes.

When you rewrite a magento class you are not changing old magento class (you would be in trouble if you did because your php class definition for your new class is probably extending it).

So, if you create an abstract class that extends an existing magento abstract class, there is no point in putting it in your XML as a rewrite because there is never a call to do the “...Abstract” job.

The abstract php class provides common behaviour for a number of other classes. The abstract class does not correspond to a job and, even if it did, changing it would not change the behaviour of the classes inheriting from it because the class name is embedded in the PHP of its inheriting classes (directly or indirectly via the extends part of the class definition).

This is why you are stuck with rewriting all of the inheriting classes to make use of your changed abstract class. You are really updating a collection of jobs to use your own classes and those classes are inheriting your own (abstract) common behaviour.

So far so good, but we now hit a bump - PHP does not support multiple inheritance:

When we specialise the abstract class and then go on to create our own invoice class we want to inherit from our abstract class AND from the existing invoice class - I want the new specialised abstract methods and I want to specialise the existing invoice methods.

We dont want to copy the old invoice class into our invoice class because that gets us into difficulty regarding upgrades and is a nasty amount of repetition just waiting to come back and bite us in the future.

The best compromise is to make a static reference to the methods you need in your specialised class.

So - as a quick example:

You can extend Mage_Sales_Model_Order_Pdf_Abstract thus:

abstract class Pwc_Sales_Model_Order_Pdf_Abstract extends Mage_Sales_Model_Order_Pdf_Abstract {
    protected function _setFontRegular($object, $size = 10)
        return parent::_setFontRegular($object, $size);

Then you can create your own invoice class to use it (and put the necessary rewrite in your module config.xml so it does the job of producing the pdf invoice):

class Pwc_Sales_Model_Order_Pdf_Invoice extends Pwc_Sales_Model_Order_Pdf_Abstract {
    public function getPdf($invoices = array()){
        return Mage_Sales_Model_Order_Pdf_Invoice::getPdf($invoices);
    public function newPage(array $settings = array()){
        return Mage_Sales_Model_Order_Pdf_Invoice::newPage($settings);

You need a static call for each method in the class you are specialisingand you may need to add any vars you see declared there too. There are some other (rather more gory) ways to accomplish this but I think this is the best compromise for complexity versus elision (not repeating code).

Fixing this properly would be fun but dont expect Varien to do it any time soon - it almost certainly requires a major rewrite and its really banging its head against the capability of PHP to implement complex systems.
by Paul Whipp



0 条评论。


注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>