Opcode (APC/XCache), Zend, Doctrine, and Autoloaders - zend-framework

I am trying to use either APC or XCache as an opcode to cache my php pages. I am using it with Zend and Doctrine and it's having a problem with the autoloader.
If I try with APC, I get the following:
Fatal error: spl_autoload() [<a href='function.spl-autoload'>function.spl-autoload</a>]:
Class Doctrine_Event could not be loaded in
C:\\[mydir]\\library\\doctrine\\Doctrine\\Record.php on line 777
If I try with XCache I get the following:
PHP Fatal error: Cannot redeclare class Zend_Registry in
C:\\[mydir]\\library\\zendframework\\Zend\\Registry.php on line 0
I'm running Zend 1.9.1, Doctrine 1.1 on a windows box.
My bootstrap is as follows:
set_include_path(dirname(__FILE__).'/../library/zendframework'
. PATH_SEPARATOR . dirname(__FILE__).'/../library/doctrine'.....
require 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->suppressNotFoundWarnings(false);
$loader->setFallbackAutoloader(true);
From what I've read, using APC or xcache is almost a must for performance, but I can't seem to get it working. Any ideas?

You could put a "Zend_Session::writeClose(true);" at the end of your index.php.
This will write the session into a persistent state before necessary Objects (Zend_Loader etc.) get destructed.
Better: Register it as shutdown function.
So it will be executed even if you use exit(), die() or a fatal error occures:
register_shutdown_function(array('Zend_Session', 'writeClose'), true);

It is probably similar to the problem with custom session handling and APC-cache. If you have assigned a custom session handler it is registered with RSHUTDOWN in PHP. It is the same routine that APC uses and will therefor create an internal conflict in PHP and your custom session handler will not close in all situations.
So you will have to make sure you manually close the custom session handler at shutdown
Putting a "Zend_Session::writeClose(true);" at the end of your index.php is not the best way to do that in case you have any exit; calls in your scripts anywhere.
It is better to register a shutdown handler in this way:
function shutdown()
{
Zend_Session::writeClose(true);
}
register_shutdown_function('shutdown');
Put that in top of your index.php file to make sure that the shutdown procedure is registered before any other scripts are run.

Is there something else mucking the include path? Maybe try to log out the include path right before that line in your first APC example.
The XCache one is really weird. That project is pretty dead though, and I'd not trust it on PHP 5.2+. Try eaccelerator instead? We've had the best luck with it.

Benjamin Cremer, you're a life saver. While the above (original) problem is a special case of autoloading with sessions, closing the session seems to be a general solution for such cases. A note though:
Placing Zend_Session::writeClose(true); at the end of your scripts may not always cut it, since you may have exit;'s, die();'s, etc in your code. In this case, you can use
register_shutdown_function(array('Zend_Session', 'writeClose'), true);
or, simply
register_shutdown_function('session_write_close');
if you do not use Zend for sessions.

Related

Why Zend_Debug::dump() doesn`t working

I was trying to use this function like this:
$test = 'tekst';
Zend_Debug::dump($test);
It does not print anything ...
Maybe this part of code is not actually running? (is this part of larger website?)
Maybe you didn't have Zend loaded, and your PHP shows error (like 'Can't find class Zend_Debug') but you have error_reporting disabled?

how to change mysql_query to mysqli_guery

I am using in a script mysqli_query but i think there is something wrong with the syntaxes. The script did work before, but changing everything form mysql_query to mysqli_query, data is not put anymore correct in the database.
This was the original query:
mysql_query( "INSERT INTO download_manager (SET filename='".mysqli_real_escape_string($_GET['file'])."'),
ON DUPLICATE KEY UPDATE downloads=downloads+1");
I changed it with mysqli_query this way:
mysqli_query($link, "INSERT INTO download_manager (SET filename='".mysqli_real_escape_string($_GET['file'])."'),
ON DUPLICATE KEY UPDATE downloads=downloads+1");
Can someone tell me what i did wrong?
Update:
My connection looks like this:
$link = #mysqli_connect($db_host, $db_user, $db_pass, $db_database) or die ("Error " . mysqli_error($link));
mysql_set_charset('utf8');
Ensure that the handle stored in $link was generated from a call to mysqli_connect and not mysql_connect:
http://php.net/manual/en/function.mysqli-connect.php
If that fails, check for an error:
die(mysqli_error($link))
Troubleshooting
The mysql and mysqli PHP modules are distinct, and you can't mix functions between the modules.
Enable error reporting to ensure you are able to see useful error messages.
Ensure the database credentials and connection details are valid.
Use mysqli_error after mysqli_xxx function calls to detect issues within the mysqli module.
Use the # token sparingly to avoid hiding useful errors.

Magento - Error after disabling modules

I've disabled the Rss and Newsletter modules of my Magento 1.7 instance following the instructions of this post:
http://inchoo.net/ecommerce/magento/how-to-fully-disable-turn-off-magento-module/comment-page-1/#comment-65853
I just edited the app\etc\modules\Mage_All.xml file by changing to <active>false</active> in both Mage_Rss and Mage_Newsletter modules.
The problem is that when I try to load a customer page through admin panel, I get the following error:
Fatal error: Call to a member function loadByCustomer() on a
non-object in app\code\core\Mage\Newsletter\Model\Subscriber.php on
line 267
Why is it happening? Why is this code being executing even though I've disabled such module?
Thanks!
First step after disabling a module through its <active> entry. Always clear cache and if you use the compiler, recompile so you don't have code referencing classes in the disabled module.
Often the problem is not with code executing after the module is shut off through the app/etc/modules/mod_name.xml by setting <active> to false, but with other modules, templates or layouts attempting to call code in the disabled module.
Where issues come in are if another module lists the module just turned off in its dependency list. Always check all the other module xml files dependency lists for mention of the module you are deactivating.
Also, you have to check for template .phtml files that reference classes in the disabled module. This can throw the dreaded call to a non-object type exception errors. As an example, one module that provides custom cart attributes asks you to add entries to your cart templates. Shutting off the module does not get rid of the references.
Make sure no layouts are attempting to load anything referencing this module as well (custom layout local.xml).
You also might want to go to System Config, Advanced and shut the Newsletter module output off there in case the Magento Customer Account is depending on testing for the module being disabled by calling that entry instead of actually checking to see if the Module is loaded. Sometimes Magento programmers forget to do proper error trapping, which has thrown me for a loop before.
I believe I could solve the problem (not sure if generated any side effect):
Just edited the file app\code\core\Mage\Adminhtml\Block\Customer\Edit\Tabs.php around line 90 by adding the external if clause:
if (Mage::helper('core')->isModuleEnabled('Mage_Newsletter')) {
if (Mage::getSingleton('admin/session')->isAllowed('newsletter/subscriber')) {
$this->addTab('newsletter', array(
'label' => Mage::helper('customer')->__('Newsletter'),
'content' => $this->getLayout()->createBlock('adminhtml/customer_edit_tab_newsletter')->initForm()->toHtml()
));
}
}
+1 if I saved your day and please let me know if you noticed and possible impact :D

Strange problem getting $ENV{'QUERY_STRING'}

I'm having a strange problem here. I'm moving a (working) site to a new apache server to which I don't have direct access (I have to go through two people to get stuff done).
The site uses a perl script called adframe to parse html templates. The URLs with which it's called look like /cgi-bin/adframe/index.html?x=something with adframe being the script. The missing suffix never caused any real problems. But on this new Ubuntu server $ENV{'QUERY_STRING'} is always empty. $ENV{'REQUEST_METHOD'} shows up correctly as GET, but the query_string shows nothing ...
Regular *.cgi scripts show the query_string without problems.
From the logs I gathered that the server seems to be running fastcgi, mod_fcgid and the server doesn't even accept .pl as an extension for scripts. I don't have that much experience with server software, but I figured it might be a problem with the server not accepting adframe as a cgi script and thus not passing the query_string correctly ... Can anyone give me a few hints to where I could point the administrator or maybe something I could do in .htaccess myself? Anyway to make sure, adframe is recognized as a cgi script!? (if that's the problem ...)
Any help is appreciated!
thomas
EDIT: I found more details: The server seems to be running a VARNISH cache ... thats's the main difference to my usual configurations ...
Also, the way the script works is, if you call /cgi-bin/adframe/somedir/somefile.html?x=something, $ENV{PATH_INFO} tells which template to parse and $ENV{QUERY_STRING} is, well, the query string. Now the query string is empty, but if I call /cgi-bin/adframe?x=something (without any PATH_INFO), the query string shows up!
Does anyone have an idea what's going on here?
thanks!
Got it. The VARNISH cache strips all the query strings off static content (*.html etc) ... phew
Just ran into the same problem. I am complete newbie in perl scripting.
I tried following:
#values = split (/&/, $ENV{'QUERY_STRING'});
but it didn`t work
this worked:
#values = split (/&/, "$ENV{'QUERY_STRING'}");
just in case if other newbies have ran into the same problem.

Zend Framework 1.9 addModuleDirectory not working?

Ok, I'm frustrated beyond words!
I have a ZF 1.9 application. The following is in my bootstrap.php:
$front = Zend_Controller_Front::getInstance();
$front->addModuleDirectory(dirname(__FILE__).'/modules');
I've put some trace code into the ZF library files, and I can see the call to addModuleDirectory and the subsequent internal call to addControllerDirectory - it's got the right values for the module name and the path. If I dump the internal _controllerDirectory variable (this is all in Library/Controller/Dispatcher/Standard.php, by the way), I can see my module directory.
The next thing my trace shows is that the default controller directory is added for the default controller - perfect.
However, on the next call to dispatch(), I'm again dumping the _controllerDirectory variable and it's only got the default module's controller directory. WTF? I have the trace going to a file... here it is (commented by me):
-- first call, triggered by addModuleDirectory():
Adding 13:09:08
Module itemquestion
Path /Users/don/Documents/Aptana Studio Workspace/cahoots2/application/modules/itemquestion/controllers
-- You can see my dir is in here...
_controllerDirectory contains: 13:09:08
/Users/don/Documents/Aptana Studio Workspace/cahoots2/application/modules/itemquestion/controllers
-- second call, triggered internally by ZF:
Adding 13:09:08
Module default
Path /Users/don/Documents/Aptana Studio Workspace/cahoots2/application/controllers
-- Where's my directory????
_controllerDirectory contains: 13:09:08
/Users/don/Documents/Aptana Studio Workspace/cahoots2/application/controllers
What in the world am I doing wrong? Why can't I get my module's directory to stay persistent?
EDIT: Some additional detail. I added a second module to the /modules folder. Now, I can see the first module being added and showing up in the _controllerDirectory variable. Then, I can see the second added, and see BOTH of them in the variable. Then I see the default module added and after that call, it's the only thing in _controllerDirectory.
Okay, it seems the solution is to add this to the application.ini:
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
Which is kinda unintuitive and at the very least not even remotely documented in the ZF reference manual. Oy. But this seems to have solved the problem.
Well I think it depends on what part you put it on the bootstrap, because, if you put it before the Application Resource Controller then it may overwrite. To make sure the front controller is bootstrapped you can use something like this:
protected function _initFrontModules() {
$this->bootstrap('frontController');
$front = $this->getResource('frontController');
$front->addModuleDirectory('path/to/modules');
}
If you omit the bootstrap line it may execute first your method and then overwrite it with the one from the plugin.