views:

22

answers:

3

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"?

+1  A: 

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

Col. Shrapnel
Changes to the main code is not an option in this case-- I'm a contractor and so is the company responsible for the code base. I have "political capital" with the client that I can use to force changes through, but I'm only going to use it for critical things like security holes.
justkevin
+1  A: 

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/"

Stewie
A: 

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

Wrikken