spl_autoload server related issue - php

We seem to have a very strange problem with the spl_autoload on 1 particular servers.
Warning: spl_autoload() [function.spl-autoload]: Unable to access file.php
public function loadClass($className) {
if(substr($className, -5) == 'Override') {
$classes = glob(_ROOT_DIR_ . 'classes/*/override/*/*.php');
foreach($classes AS $class) {
$explodePath = explode('/', $class);
$explodePath = array_reverse($explodePath);
if(file_exists(_ROOT_DIR_.'classes/'.$explodePath[3].'/override/'.$explodePath[1].'/'.$explodePath[0])) {
set_include_path(get_include_path().PATH_SEPARATOR._ROOT_DIR_.'classes/'.$explodePath[3].'/override/'.$explodePath[1].'/');
spl_autoload(strtolower($className));
}
}
}
return FALSE;
}
Also I have checked and in our WHM panel it shows the include path is set to
.:/usr/lib/php:/usr/local/lib/php
This particular server is Linux RedHat-9.3.6 running PHP 5.3.8 & eAccelerator
the code above has been testing on 10 other servers and works fine so really at lost to why this would be happening on this particular server.
We would really like to use the spl_autoload method instead of include/require which would slow down our application.
Please I hope someone can offer some advice with helping us to solve this issue.

Related

How to find user's home directory on Windows and Linux in PHP

I've understood there are several ways to determine the user's home, depending on the platform (mainly Unix/Linux vs Windows).
Composer uses an environment variable, in composer/Platform package:
public static function getUserDirectory()
{
if (false !== ($home = getenv('HOME'))) {
return $home;
}
if (self::isWindows() && false !== ($home = getenv('USERPROFILE'))) {
return $home;
}
if (function_exists('posix_getuid') && function_exists('posix_getpwuid')) {
$info = posix_getpwuid(posix_getuid());
return $info['dir'];
}
throw new \RuntimeException('Could not determine user directory');
}
public static function isWindows()
{
return defined('PHP_WINDOWS_VERSION_BUILD');
}
Webmozart's path-util package uses other environment variables:
public static function getHomeDirectory()
{
// For UNIX support
if (getenv('HOME')) {
return static::canonicalize(getenv('HOME'));
}
// For >= Windows8 support
if (getenv('HOMEDRIVE') && getenv('HOMEPATH')) {
return static::canonicalize(getenv('HOMEDRIVE').getenv('HOMEPATH'));
}
throw new RuntimeException("Your environment or operation system isn't supported");
}
What is the difference between these two methods? Is one more reliable than the other?
Note: I'm using PHP in the CLI, so it's always the actual current user running PHP.
EDIT> I understand that this question seems to ask for an opinion, but it's not the case. I DO NOT KNOW Windows and do not understand why some packages use different ways to determine the user's home directory. I'm asking for explanations about the two mentioned methods: is one of them more reliable than the other and why?
I've edited the title and the question to reflect this precision.
After not working on this for a long time, I finally decided to definitely answer this question.
There are some usefull environment variables defined on Windows: USERPROFILE, APPDATA, LOCALAPPDATA. They are easily accessible via getenv() function:
getenv('USERPROFILE');
USERPROFILE exists on any Windows, according to https://learn.microsoft.com/fr-fr/windows/desktop/shell/knownfolderid
So, on Windows, it seems to be reliable.
If you need to store data for the current user, APPDATA and LOCALAPPDATA are good variables to find that place.
I've written a package to make these tools reusable: https://github.com/Arcesilas/Platform
It's still work in progress and certainly needs to be improved. Any help is welcome to make this tool reliable on any platform.
Thanks to eryksun whose comments helped a lot in solving this question.

Deploying a Symfony App to Google App Engine

I’ve read the documentation on https://cloud.google.com/appengine/docs/php/symfony-hello-world and I managed to deploy the Hello World app, but when I try with my symfony app I have his error:
InvalidArgumentException in XmlFileLoader.php line 259: Unable to parse file "(…) DependencyInjection/../Resources/config\web.xml".
In app.yaml I set the env variables:
env_variables:
GCS_BUCKET_NAME: "pinterpandaibucket"
CACHE_DIR: "gs://pinterpandaibucket/symfony/cache"
LOG_DIR: "gs://pinterpandaibucket/symfony/log"
And I overloaded the AppKernel.php functions:
public function __construct($environment = null, $debug = null)
{
// determine the environment / debug configuration based on whether or not this is running
// in App Engine's Dev App Server, or in production
if (is_null($debug)) {
$debug = !Environment::onAppEngine();
}
if (is_null($environment)) {
$environment = $debug ? 'dev' : 'prod';
}
parent::__construct($environment, $debug);
// Symfony console requires timezone to be set manually.
if (!ini_get('date.timezone')) {
date_default_timezone_set('UTC');
}
// Enable optimistic caching for GCS.
$options = ['gs' => ['enable_optimsitic_cache' => true]];
stream_context_set_default($options);
$this->gcsBucketName = getenv('GCS_BUCKET_NAME');
...
public function getCacheDir()
{
if ($this->gcsBucketName) {
return getenv('CACHE_DIR');
}
return parent::getCacheDir();
}
public function getLogDir()
{
if ($this->gcsBucketName) {
return getenv('LOG_DIR');
}
return parent::getLogDir();
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load($this->getRootDir().'/config/config_'.$this->getEnvironment().'.yml');
}
}
?>
The functions which write to the file system are redirected to the bucket.
Could you help me to find what modifications are missing in my app.
I hope this topic will help someone else because the Google cloud documentation isn't very up to date.
Thank you in advance and sorry if I don’t speak English very well I’m a French IT student.
Augustin
I have spent many an hours on this horrible bug, and what I found was this issue happens on the Dev AppServer, but not in production. I believe it is an issue with the implementation of the xml.so php extension in that environment.
This is fixed in the symfony starter app with the method fixXmlFileLoaderBug, which gets called in web/app.php. So ensure this is being called, and you should be good to go.
If you're experiencing this bug in Production, or you continue to experience this issue even after calling this function, please let us know by filing an issue on github.

Very high latency in first HTTP request on CodeIgniter project

A friend and I just started working in a project which other people stopped developing a couple of years ago, and we're trying to resurrect it. We've already solved most of the setup-related issues, but there's a really annoying one that we can't figure out.
In our localhosts, all the pages take A LOT of time to load/refresh. And I don't mean assets, scripts or anything, the problem is the latency until the first request completes. Most times it takes 15 to 30 seconds, which is unacceptable, and sometimes it even goes up to 1 or 2 minutes.
For example, here's a screenshot of the Network tab in Chrome dev tools. The first row is the view, the other ones are assets.
We've googled for hours and tried a few different things, but none of them has worked. Some solutions like this one point to some Apache's httpd.conf settings, but I discarded that since I'm using the same server for other projects and this never happened (I tried it anyway, but didn't work). Others point to PHP version conflicts, so I tried changing the PHP in my MAMP from 5.4.10 to 5.2.17 (the project requires 5.2.3+), but that didn't seem to work either.
Apart from my MAMP installation, we also tested it in a Windows machine with WAMP (PHP5.5), and also in another Mac with a clean MAMP (PHP5.5), and the same thing happens in both environments. So, we are now wondering if the problem could be in CodeIgniter itself (which sounds unlikely) or in some project configuration, but we're pretty new to CodeIgniter (and also not PHP experts) and couldn't find anything.
Oh, and we also tried contacting the original developers, but they said that was two years ago and sounded like they're unwilling to help. I really hope they didn't have this issue while developing the project back then, because working with 30sec load times it's just insane.
Someone have any idea or know about something more we could try to find the issue? I could post some code if needed.
Update: I just found this unsolved question where a user experienced a similar issue with Laravel, but only sometimes. As I said, in my case this happens always, with latency times spanning from ~10 seconds to a few minutes.
Update 2: As suggested by Wrikken, i ran it through an xdebug profiler, but I'm not sure of how to interpret the results to see where the issue is. I opened a snapshot with PHPStorm's "Analyze Xdebug Profiler" tool, and sorted it by time used in each call. Here are a couple of screenshots:
And sorted by Own Time:
That CashewModel showing up in some lines is a some sort of custom library built by the previous developers, which was also causing some problems we already solved. I hope the problem isn't hidden there, because I have no idea of how most of that custom code works.
Any ideas? Again, I can post code if needed.
Update 3: Digging into the code, that MY_Controller in the screenshot above is a file where the previous developers created some custom controllers extending CI_Controller. I just found out that they pushed all the Cashew code to GitHub, here's the MY_Controller file.
I'll also paste here all the relevant code around line 467 (in GitHub's version is 464), which involves the _remap function inside the CashewController and is where the profiler says all the time is spent. I translated some comments and names into English.
/**
*
* Extension of the default controller, adding support for templates
*
* Usage example:
*
* class Dummy extends EC_Controller
* {
* public function index()
* {
* $this->add_section('id_in_template', 'page_name');
* $this->render_page(); // Renders the default template.
* }
* }
*
*/
class CashewController extends CI_Controller
{
//
// Some attributes here
//
function __construct() { ... }
/**
* We use this _remap to automatically create the CRUD method calls
*
* #param string $method
* #param string $params
*/
public function _remap($method, $params = array())
{
// NEW
if ($method == 'new') {
$method = '_new';
}
// CREATE
else if ($method == 'index' && $this->request_method() == 'post') {
$method = '_create';
}
else if (is_numeric($method) && $this->request_method() == 'post' && count($params) == 0) {
$params[0] = $method;
$method = '_create';
}
// SHOW
else if (is_numeric($method) && count($params) == 0) {
$params[0] = $method;
$method = '_show';
}
else if (is_numeric($method) && count($params) == 1 && $params[0] == 'edit') {
// EDIT
if ($this->request_method() == 'get') {
$params[0] = $method;
$method = '_edit';
}
// UPDATE
else if ($this->request_method() == 'post') {
$params[0] = $method;
$method = '_update';
}
}
// DELETE
else if (is_numeric($method) && count($params) == 1 && $params[0] == 'delete') {
$params[0] = $method;
$method = '_delete';
}
if (method_exists($this, $method)) {
return call_user_func_array(array($this, $method), $params);
}
show_404();
}
//
// Some more functions
//
}
So something's happening inside that call_user_func_array(array($this, $method), $params), right?
I found the issue thanks to a comment posted above but the user didn't write an answer, so I'm posting it here.
The code written by the previous developers is making a pretty intensive use of the memcached extension, which I never used before, so I didn't know what it was or that I needed to enable it in my computer. I followed the steps here and that was it, load times are acceptable now.
Thanks everyone!
That sounds like a timeout on a domain or host-name look-up (or IP reversal), a bad localhost resolve to the IPv6 ::1 (with a fallback to 127.0.0.1), or an HTTPS request that timeouts out when doing a certificate revocation list check (you'd need to remove that option from whatever function that is handling this).
I had the same problem. Some of the potential solutions are:
1. You might have debug mode on.
2. The cache might not be setup. Set it to auto cache.
If none of them works out, try using docker for codeigniter which worked out foe me.
Hope it helps.

Translating paths in PHP from (*nix) server to (winxp) dev machine

I'm working on a PHP project that has a lot of hard coded paths in it. I'm not the main developer, just working on a small part of the project.
I'd like to be able to test my changes locally before committing them, but my directory structure is completely different. For example, there's a lot of this in the code:
require_once("/home/clientx/htdocs/include.php")
Which doesn't work on my local WAMP server because the path is different. Is there a way to tell either WAMP or XP that "/home/clientx/htdocs/" really means "c:/shared/clients/clientx"?
If its a local copy, do a search and replace on the whole directory , Please don't forget trailing slash. And when you commit the code, do reverse.
This is the solution, if you don't want to add extra variables and stuff (because that would change other developers' code/work/dependencies (if any)
search "/home/clientx/htdocs/" and replace to this: "c:/shared/clients/clientx/"
Always use $_SERVER['DOCUMENT_ROOT'] instead of hardcoded path.
require_once($_SERVER['DOCUMENT_ROOT']."/include.php")
as for your wamb environment, you will need a dedicated drive to simulate file structure. You can use NTFS tools or simple subst command to map some directory to a drive.
Create /home/clientx/htdocs/ folder on this drive and change your httpd.conf to reflect it.
But again, you will do yourself a huge favor by convincing your coworkers to stop using hardcoded paths
WARNING: ONLY USE THIS SOLUTION FOR EMERGENCY REPAIRS, NEVER FOR LONGER PRODUCTION CODE
Define a class with rewriting methods, see http://php.net/manual/en/class.streamwrapper.php
<?php
class YourEmergencyWrapper {
static $from = '/home/clientx/htdocs/';
static $to = 'c:/shared/clients/client';
private $resource = null;
//...some example stream_* functions, be sure to implement them all
function stream_open($path,$mode,$options=null,&$opened_path){
$path = self::rewrite($path);
self::restore();
$this->resource = fopen($path,$mode,$options);
self::reenable();
$opened_path = $path;
return is_resource($this->resource);
}
function stream_read($count){
self::restore();
$ret = fread($this->resource,$count);
self::reenable();
return $ret;
}
function stream_eof(){
self::restore();
$ret = feof($this->resource);
self::reenable();
return $ret;
}
function stream_stat(){
self::restore();
$ret = fstat($this->resource);
self::reenable();
return $ret;
}
static function rewrite($path){
if(strpos($path,self::$from)===0) $path = self::$to.substr($path,strlen(self::$from));
return $path;
}
//... other functions
private static function restore(){
stream_wrapper_restore('file');
}
private static function reenable(){
stream_wrapper_unregister('file');
stream_wrapper_register('file',__CLASS__);
}
}
stream_wrapper_unregister('file');
stream_wrapper_register('file','YourEmergencyWrapper');
Seriously, only some local debugging on your own dev-server. You can force it as an auto_prepend on almost any code. Left some function yet be implemented ;P

/tmp/cache directory problem

I have just started out with testing some php mvc framework
In it, it has this function that throws an error.
The cachedirectory is set to /tmp/cache from the config file
additional:
The php is hosted on an IIS server.
Can someone help me out to get this working somehow?
This is the function within the class
function setCacheDir($cacheDir = null)
{
if( is_null( $cacheDir ) )
{
$config = config::getInstance();
$cacheDir = $config->config_values['template']['cache_dir'];
}
if (is_dir($cacheDir) && is_writable($cacheDir))
{
$config = config::getInstance();
$this->cache_dir = $cacheDir;
}
else
{
throw new Exception("De cache directory '$cacheDir' either does not exist, or is unwriteble");
}
}
thanks, Richard
Why don't you set the cache directory to something a little more Windows-y, like c:\temp (and make sure that folder exists).
I'm guessing "/tmp/cache" doesn't exist and isn't writable, so in the configuration file, set cache_dir to a directory that is.
Some PHP frameworks work best (or better) in a LAMP stack, the first letter (L) being Linux. If the documentation of your framework advises a LAMP stack, I'd go with that.

Categories