4

I'm trying to run magmi product import plugin on a Magento app which is running on an aws ec2 instance that has NGINX & HHVM on it. When I try to run the the magmi product import app on Magento I get the below server error in my hhvm error log.

/var/log/hhvm/error.log

\nCatchable fatal error: Object of class Magmi_ProductImportEngine could not be converted to string in /var/www/qa-hoi/magmi-importer/inc/magmi_mixin.php on line 9

This is the magmi_mixin.php file

<?php
class Magmi_Mixin
{
    protected $_callers;

    public function bind($caller)
    {
        $this->_callers[]=$caller;
        $this->_callers=array_unique($this->_callers);  // LINE 9   
    }

    public function unbind($caller)
    {

        $ks=array_keys($this->_callers,$caller);
        if(count($ks)>0)
        {
            foreach($ks as $k)
            {   
                unset($this->_callers[$k]);
            }
        }

    }

    public function __call($data,$arg)
    {
        if(substr($data,0,8)=="_caller_")
        {
            $data=substr($data,8);
        }
        for($i=0;$i<count($this->_callers);$i++)
        {
            if(method_exists($this->_callers[$i],$data))
            {
              return call_user_func_array(array($this->_callers[$i],$data), $arg);
            }
            else
            {
                die("Invalid Method Call: $data - Not found in Caller");
            }
        }
    }
}

Any idea how I should go about solving this? Should I update my php.ini file?

What could be causing the fatal error. It is not occurring on my local machine which has Apache.


UPDATE

I installed HHVM on my local machine and ran the xdebug. It seems that the $caller object in the magmi file contains several arrays that cannot be evaluated. See screenshot below:

Xdebug Screen Shot

Holly
  • 7,462
  • 23
  • 86
  • 140

2 Answers2

3

I had the same issue. My solution was to simply comment out the offending line.

    public function bind($caller)
{
    $this->_callers[]=$caller;
    // $this->_callers=array_unique($this->_callers);  // LINE 9   
}

You may also find Magmi is getting a "500 hphp_invoke" error on /magmi/web/magmi_run.php. To get around this I added an exception handler within the first if statement. My magmi_run.php file now reads...

<?php
$params = $_REQUEST;
ini_set("display_errors", 1);
require_once ("../inc/magmi_defs.php");
require_once ("../inc/magmi_statemanager.php");
try {
    $engdef = explode(":", $params["engine"]);
    $engine_name = $engdef[0];
    $engine_class = $engdef[1];
    require_once ("../engines/$engine_name.php");
} catch (Exception $e) {
    die("ERROR");
}
if (Magmi_StateManager::getState() !== "running") {
    try {
        Magmi_StateManager::setState("idle");
        $pf = Magmi_StateManager::getProgressFile(true);
        if (file_exists($pf)) {
            @unlink($pf);
        }
        set_time_limit(0);
        $mmi_imp = new $engine_class();
        $logfile = isset($params["logfile"]) ? $params["logfile"] : null;
        if (isset($logfile) && $logfile != "") {
            $fname = Magmi_StateManager::getStateDir() . DIRSEP . $logfile;
            if (file_exists($fname)) {
                 @unlink($fname);
            }
            $mmi_imp->setLogger(new FileLogger($fname));
        } else {
            $mmi_imp->setLogger(new EchoLogger());
        }
        $mmi_imp->run($params);
    } catch (Exception $e) {
        die("ERROR");
    }
} else {
    die("RUNNING");
}
?>
R1CHY_RICH
  • 68
  • 8
  • Thanks that worked. I only had to comment out the line _magmi_mixin.php_, I don't know how I did not try that! I didn't need to change _magmi_run.php_, I wonder why you had to and I did not? Anyway thanks for the answer :) – Holly Jul 13 '15 at 14:55
  • it worked for me also :) , I'm trying to figure why is it happen if I found I'll post here – Chamal Chamikara Sep 07 '15 at 14:13
  • It appears HHVM handles arrays differently. We found another issue related to this in regards to the tax calculation on the cart page. This post sums it all up [here](http://magento.stackexchange.com/questions/67359/magento-subtracting-tax-from-subtotal-instead-of-adding-it) – R1CHY_RICH Sep 08 '15 at 00:36
1

HHVM is far more restrictive than PHP is, when it comes to the deprecated constraints and functions, warning and notices, so it is not uncommon that (not so well-written) code working well in PHP does not work properly in HHVM.

With regards to you particular issue:

As per the documentation of HHVM, this is what is happening in your line #9, the problem is in the parameter to array_unique (refer to http://docs.hhvm.com/manual/en/function.array-unique.php):

array_unique($this->_callers)

The HHVM Manual states:

function array_unique ( array $array [, int $sort_flags = SORT_STRING ] ): array

Which means that the array you pass to array_unique as the first parameter, because the second parameter defaults to SORT_STRING, is expected to only contain string elements or elements of other types as long as they are all directly convertible to string.

Objects are only convertible to string if they define (or inherit) the "magic" method __toString().

One solution, therefore, would be to amend the code of your Magmi_ProductImportEngine class, adding something like:

class Magmi_ProductImportEngine /* extends whatever */ {
     // ... other stuff

     public function __toString() {
         return 'array representation of the object as string for sorting purposes';
     }

     // ... other stuff
}

However, I wouldn't expect the same code to work with no errors in Apache mod-php either, (it should fail with the "PHP Catchable fatal error: Object of class Magmi_ProductImportEngine could not be converted to string"), perhaps in your Apache version the array "$this->_callers" does not contain an instance of Magmi_ProductImportEngine among elements?

Orvid King
  • 1,188
  • 10
  • 16
Dmitri Sologoubenko
  • 2,909
  • 1
  • 23
  • 27
  • Although it doesn't affect the substance of your answer, HHVM in general is not supposed to be any more strict than PHP5 is when running PHP code. If there's a case where it is doing so, you should file an issue on GitHub against HHVM. – Josh Watzman Jun 27 '15 at 05:44
  • @Dmitri Thanks, I'm not sure what to put in as the return value for the `__toString()`. I copied your code and get a new error in the HHVM log `\nCatchable fatal error: Object of class Magmi_CSVDataSource could not be converted to string in /var/www/qa-hoi/magmi-importer/inc/magmi_mixin.php on line 9` – Holly Jun 27 '15 at 06:21
  • @Josh, the value returned by `__toString()` is used for sorting. If the order of the objects in your `_callers` array is not important, you can return any value, including an empty string. The new error for `Magmi_CVSDataSource` is because of the same reason: missing `__toString()` method: perhaps these objects are not supposed to be part of the `_callers` array? – Dmitri Sologoubenko Jun 29 '15 at 08:51
  • @Josh, there are some deprecated language features that PHP still supports and HHVM does not (I'm not suggesting HHVM is wrong in doing that) and security-related settings that have different default values, sometimes breaking applications. I know these are features, not bugs, but - nonetheless - it may create issues in existing PHP code. Also, detecting these issues is quite complicated in HHVM (as it is not yet very well documented). – Dmitri Sologoubenko Jul 14 '15 at 20:00