Today a Magento store owner asked me why he could not create a new attribute set based on an existing one. I took a look into his store and found out the existing attribute set has many custom attributes, which led to new attribute set creation would take more than 30 seconds. But 30 seconds is the default PHP max execution time, which is set in php.ini and has not been optimised for Magento backend operation.
My immediate reaction was changing the default value of max_execution_time to 120. I added a line in /etc/php-fpm.d/www.conf, where is my preferential place to set server wide PHP directives rather than /etc/php.ini.
php_admin_value[max_execution_time] = 120
After a while, I had another thought. I do not like to extend PHP max execution time for most of other websites on the same server. Even for the Magento store, longer execution time is only needed for the backend operations. So how can I specify different PHP directives for different websites? Particularly, how can I specify longer execution time or larger memory limit for Magento admin users?
My first idea was creating separate php-fpm (Yes, I am using php-fpm.) profiles for this purpose. However, I rejected this idea after 2 seconds, because:
- I do not like to create more PHP daemons into the valuable server memory.
- If Magento frontend and backend are on the same domain, I have no way to assign a corresponding daemon.
So, can I implement changing run-time PHP directives using a Magento module? Of course. I had a Magento module called Msdk (Magento SDK). I just need to add this feature to Msdk.
Firstly, I need to find a proper event to catch. The event should be dispatched only once per request, and earliest possible when it can distinguish frontend or adminhtml route. The earliest event is “controller_front_init_before” except some database events, which are not recommend to catch anyway. But “controller_front_init_before” can not distinguish frontend or adminhtml route, i.e. it can only be put into global section in config.xml. Following the event timeline, I find “frontend or adminhtml route” is the best event to catch.
Secondly, I put one “controller_front_init_before” event catching into frontend section and another into adminhtml section in config.xml of Msdk module.
Thirdly, write two observers in a Helper or a Model to apply PHP directives.
Lastly, modify system.xml to allow users to set PHP directives in Magento System Configuration.
It sounds complicated but actually not. I finished it in a couple of hours.
BTW, Msdk is one of my free modules. But I am not going to launch it now with only one new feature. Watch the space for updated news.