开发者

Is it possible to use Magento's existing / included Zend Framework in another app?

I want to make a little Zend app that runs along side our Magento (Enterprise) install. Can I use the existing Zend code included with Magento? Or do I need to have another separate copy of Zend?

I am afraid that Varien has probably messed with the framework code. Just looking it appears they have commented out all require() statements, which is throwing lots of errors (obviously). The Zend AutoLoader won't work, at any rate. Is there a way to use the开发者_开发技巧 Varien AutoLoader instead?

I don't particularly want to import another framework (3000+ files) into our project if I can avoid it.

Thanks!

EDIT:

Here is my dir structure:

/localsite/ -- root
/localsite/products -- Magento install
/localsite/products/lib/Zend --Zend in Mage folder
/localsite/fbtest -- my Zend Framework app root
/localsite/fbtest/application -- my Zend Framework app

Here is the code I am trying (/localsite/fbtest/public/index.php):

<?php
define('DS', DIRECTORY_SEPARATOR);

defined('APPLICATION_PATH')
  || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

defined('APPLICATION_ENV')
  || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));

set_include_path(implode(PATH_SEPARATOR, array(
  BASE_PATH . DS . 'products' . DS . 'lib' . DS . 'Zend',
  get_include_path(),
)));

require_once('../../products/lib/Zend/Application.php');

$application = new Zend_Application(
  APPLICATION_ENV,
  APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap()
        ->run();

Here is the error:

Fatal error: Class 'Zend_Loader_Autoloader' not found in C:\xampp\htdocs\localsite\products\lib\Zend\Application.php on line 81

Here is the include_path:

C:\xampp\htdocs\localsite\products\lib\Zend;.;C:\php\pear

And here is where AutoLoader should be included (in /products/lib/Zend/Application.php):

#require_once 'Zend/Loader/Autoloader.php';
$this->_autoloader = Zend_Loader_Autoloader::getInstance();

^^^ see that '#' where the require_once is commented out? I think that's a change Varien made which breaks the Framework, no? It appears to be why it's not working form me, at least? How can I get around this and include all of the commented out includes??

Thanks again


add magento's library folder to include path in index.php:

//define shortcut for DIRECTORY_SEPARATOR
defined('DS') || define('DS', DIRECTORY_SEPARATOR);
//define base bath obtainable throughout the whole application
defined('BASE_PATH')
    || define('BASE_PATH', realpath(dirname(__FILE__) . DS . '..' . DS . 'basedir' . DS));

//define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', BASE_PATH . DS . 'app');

//set include path to libraries
set_include_path(BASE_PATH . DS . 'library' . PATH_SEPARATOR . MAGENTO_DIR . DS . 'lib' . PATH_SEPARATOR . get_include_path());

But with this approach you can't use latest ZF version. So separate install is my choice.

autoloader works, easy way here is to place original Zend/Loader/ into your application library, or include all required autoloader classes manually(just 3: loader, autoloader, Zend_Exception)

Here is my full projectName/public/index.php:

if (get_magic_quotes_gpc()) {
  function stripslashes_deep($value)
  {
    $value = is_array($value) ?
          array_map('stripslashes_deep', $value) :
          stripslashes($value);

    return $value;
  }

  $_POST = array_map('stripslashes_deep', $_POST);
  $_GET = array_map('stripslashes_deep', $_GET);
  $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
  $_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}

//define shortcut for DIRECTORY_SEPARATOR
defined('DS') || define('DS', DIRECTORY_SEPARATOR);

//define base bath obtainable throughout the whole application
defined('BASE_PATH')
    || define('BASE_PATH', realpath(dirname(__FILE__) . DS . '..' . DS . 'basedir'));

//define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', BASE_PATH . DS . 'app');

//set include path to libraries
set_include_path(BASE_PATH . DS . 'library' . PATH_SEPARATOR . get_include_path());

//bootstrap, and run application
try {
    require_once 'Zend/Application.php';
    //create application and configure it.
    $application = new Zend_Application(
        getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production',
        array('config' => array(APPLICATION_PATH . DS . 'configs' . DS . 'application.ini'))
    );
    //run application
    $application->bootstrap()->run();
} catch (Exception $e) {
 //here was logging logic
}

This is how your /localsite/fbtest/public/index.php may look:

if (get_magic_quotes_gpc()) {
  function stripslashes_deep($value)
  {
    $value = is_array($value) ?
          array_map('stripslashes_deep', $value) :
          stripslashes($value);

    return $value;
  }

  $_POST = array_map('stripslashes_deep', $_POST);
  $_GET = array_map('stripslashes_deep', $_GET);
  $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
  $_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}

//define shortcut for DIRECTORY_SEPARATOR
defined('DS') || define('DS', DIRECTORY_SEPARATOR);

//define base bath obtainable throughout the whole application
//keep your libraries and application out of public directory
defined('BASE_PATH')
    || define('BASE_PATH', realpath(dirname(__FILE__) . DS . '..' . DS . 'basedir'));

//define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', BASE_PATH . DS . 'application');

//if index.php in /localsite/fbtest/public/
defined('MAGENTO_PATH')
    || define('MAGENTO_PATH', realpath(dirname(__FILE__) . DS . '..' . DS . '..' . DS . 'products'));

//set include path to libraries
//noticed magento library added? 
set_include_path(BASE_PATH . DS . 'library' . PATH_SEPARATOR . MAGENTO_PATH . DS . 'lib' . PATH_SEPARATOR . get_include_path());

//bootstrap, and run application
try {
    require_once 'Zend/Application.php';
    require_once 'Zend/Loader.php';
    require_once 'Zend/Loader/Autoloader.php';
    require_once 'Zend/Exception.php';
    //create application and configure it.
    $application = new Zend_Application(
        getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production',
        array('config' => array(APPLICATION_PATH . DS . 'configs' . DS . 'application.ini'))
    );
    //run application
    $application->bootstrap()->run();
} catch (Exception $e) {
 //here was logging logic
}


Alright, I got it! The Zend Framework with Magento isn't really broken... but they are doing things a little different than normal.:

1) It is normal to comment out the require_once() statements in Zend when you enable "lazy loading" with the Zend Loader. It's a performance thing:
http://framework.zend.com/manual/en/performance.classloading.html

2) It is not normal to comment them out in the Application.php and Loader.php classes, however:

[keep the] require_once() calls within Zend_Application and Zend_Loader_Autoloader, as these classes will fail without them.

So, the answer is to just add the 3 missing require_once() statements yourself when enabling Loader.php. Here is my new code that works (in my apps index.php):

<?php
define('DS', DIRECTORY_SEPARATOR);

defined('APPLICATION_PATH')
  || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

defined('APPLICATION_ENV')
  || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));

set_include_path(implode(PATH_SEPARATOR, array(
  BASE_PATH . DS . 'products' . DS . 'lib',
  '.',
)));

require_once 'Zend/Loader.php';

require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance();

require_once APPLICATION_PATH.'/Bootstrap.php';

$application = new Zend_Application(
  APPLICATION_ENV,
  APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap()
    ->run();

Now I am off and running! The problem was that I just didn't really know how the auto-loader was set up. I hope this helps someone!


I am afraid that Varien has probably messed with the framework code.

I guess that would violate the terms of use (except stripping the require_once).

Zend_Autoloader should work fine IMO. Just setup the include path and you're ok ;)

Update:

I can see from your code that you have not the BASE_PATH constant defined. Therefore the include path is not defined and Zend_Loader_Autoloadercan't be loaded. If your include path would be OK, then it's fine to write require_once 'Zend/Loader/Autoloader.php'; without the path. Also there is no need to require Zend_Loader it's deprecated.

Also you're including Zend_Application not Loader. Why? Only class ever needed to be 'hardcode' required is the autoloader, using the line require_once 'Zend/Loader/Autoloade.php'; - NOTHING MORE. If it doesn't work, your include path is messed up.


The following code has enabled the usage of the Zend-Framework in a cli script. The Zend-Framework, that is delivered with Magento, has been used for the cli script.

// 1. point libPath to the <magento-root>/lib directory
$libPath=realpath(dirname(__FILE__).'../../../lib') ;

// 2. set the Zend-Framework include-path
set_include_path($libPath . PATH_SEPARATOR . get_include_path());

// 3. manual includes 

require_once 'Zend/Loader.php';
require_once 'Zend/Loader/Autoloader.php';

// 4. instantiate the autoloader
Zend_Loader_Autoloader::getInstance();

This has enabled to use Zend_Http_Client and all its dependend classes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜