Results 1 to 6 of 6

Thread: Using function opendir on a network drive

  1. #1
    Join Date
    Nov 2006
    Posts
    7
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Unhappy Using function opendir on a network drive

    Hello,

    I need major help with the opendir function in php.
    I have a network drive that I have access to by mapping to it.
    This network drive can be access on the web as well in which
    it display the directory tree of that drive.

    Now what I am attempting to do is from my web server (M: drive),
    I have a php page that I want to access the network drive (Z: drive) so
    that I can display the directory tree in this php file or page. However,
    I can not seem to get it to work.

    I have tried several ways but I can not get it to access the network drive.
    Please someone help me.

    example of my code:

    (1) $dir = "Z:\\mydirectory\htdocs";
    (2) $dir = "Z:\\\\mydirectory\\htdocs";
    (3) $dir = "Z://mydirectory/htdocs/";

    if (is_dir($dir)) {
    if ($dh = opendir($dir)) {
    print "able to access directory tree.";}}
    else {
    print "not access tree.";}

  2. #2
    Join Date
    Jan 2008
    Posts
    32
    Thanks
    0
    Thanked 3 Times in 3 Posts

    Default

    Your problem arises when you escape the wrong characters.
    The correct dir, when unescaped should be
    Code:
    Z:\mydirectory\htdocs
    We need to escape both of the backslashes with a preceding backslash.

    Your $dir 's are, as unescaped strings
    Code:
    Dir 1: Z:\mydirectory\\htdocs
    Dir 2: Z:\\mydirectory\htdocs
    Dir 3: Z://mydirectory/htdocs/
    The problem with Dir 1 is that you forgot to escape the backslash before htdocs, so it escapes "\h" not the backslash, and since "\h" is not a special character, it becomes "\\h" (but you want it to be "\h")

    The correct $dir would be
    PHP Code:
    $dir "Z:\\mydirectory\\htdocs"

  3. #3
    Join Date
    Nov 2006
    Posts
    7
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Leafy,

    I tried that and still it did not work. I am able to map to that drive but am not able to access it in my code. I don't know what I am doing wrong. Any suggestions?

  4. #4
    Join Date
    Jun 2007
    Posts
    543
    Thanks
    3
    Thanked 78 Times in 78 Posts
    Blog Entries
    1

    Default

    i have made a dir script that you can use if you want demo. just edit the
    Code:
    $defaultdir
    Last edited by Master_script_maker; 01-14-2008 at 09:22 PM.
    [Jasme Library (Javascript Motion Effects)] My Site
    /\/\@ /\/\@|{
    There are 10 kinds of people in the world, those that understand binary and those that don't.

  5. #5
    Join Date
    Mar 2009
    Posts
    2
    Thanks
    0
    Thanked 1 Time in 1 Post

    Default

    SOLUTION

    For anyone having this issue (this is the first page that google kept giving me when trying to resolve it), and indeed the original posters, here is how to get around this problem. I have found two methods that work, and here they are:



    Use FTP instead of a network drive

    PHP's opendir() accepts FTP site URL's. However, this method is flawed in a number of ways:

    • FTP is slower than a network drive unless you disable error correction, which is complicated and you don't want to do anyway.

    • If you are not accessing a machine with a built in FTP server (like win XP pro or a server OS) you have to use third party software.

    • Not all of PHP's file system functions can be performed via FTP.

    • FTP is VERY insecure.



    Prefered Solution: Map a network drive using PHP at the beginning of the script

    This solution is taken from Matt Grimm's posts on the opendir() page of the manual at PHP.net


    1) Ensure Apache (or IIS, or php.exe if your running the CLI) is running as an account that has permission to access the relevant resource (I think this is the major sticking point here, the SYSTEM account doesn't have access to mapped network drives!!, but this step alone does not solve the problem). I just ran it as "Administrator", but if you are worried about the (slight) security implications there, set up a new user account and run it under that. You can change this setting in Control Panel > Administrative Tools > Services, select the relevant service and get the properties, then select the "Log On" tab.


    2) AT THE BEGINNING of your script, map the network drive with your PHP code, using the windows "net" command's "use" function (you can map network drives from cmd with this command as well... type "net /?" at a command prompt for a basic explanation of this powerful command).


    Here's the line: (Matt Grimm got this slightly wrong)

    Code:
    system('net use Z: "\\servername\sharename" PASSWORD /user:USERNAME /persistent:no');

    Notes:
    • Use the system() command, not exec(). No idea why, but it doesn't work if you use exec(), although the command executes successfully. I haven't tried passthru(), but then why you would use it in this context I don't know...

    • You can use any unused drive letter. "Z:" is just an example.

    • If your share name contains a space, you MUST surround the path in the command with double quotes. It's good practice to do this when specifying any path for a Windows command. You must also keep the single quotes in the PHP command, and you not need to escape any back slashes. You can use an IP address instead of a name for the server if you wish.

    • Yes, it goes password, then username. Also there is no "/password" tag. Wierd, I know, but that's Microsoft for you.

      Obviously there is a bit of a security issue with storing the password in your code, essentially in plain text, so here is a nice (albeit long) tutorial on a reversible password encryption method for PHP.

    • The "/persistent:no" part is essential. The network drive you map from PHP will not be visible in explorer, even if you specify your account as the logon account for Apache. If you don't turn "/persistent" off then it is still there, invisible, after a reboot, and the re-mapping attempt when you run the script again gets an error. You can, however, run the script multiple times during one session in Windows/PHP (ie one boot) without the error.



    3) You can now access your network drive from a PHP command! Remember to escape any back slashes ( \ becomes \\ ) or you can just use forward slashes...

    Z:/an/example/path

    ...is perfectly valid. (take note, because this makes writing cross-plaform scripts a lot easier and helps you avoid all those "spent an hour trying to find the problem and forgot to escape something" incidents)



    This solution has been tested
    with: Apache/2.0.63 (Win32) PHP/5.2.8
    on: Windows XP Professional SP2/SP3, Windows Server 2003 R2 (various editions)

    However, since the issue is basically an NT auth problem, this should work with any version of PHP (including command line) and any NT based OS.
    Last edited by DaveRandom; 03-30-2009 at 09:31 PM.

  6. The Following User Says Thank You to DaveRandom For This Useful Post:

    JasonDFR (03-31-2009)

  7. #6
    Join Date
    Mar 2009
    Posts
    2
    Thanks
    0
    Thanked 1 Time in 1 Post

    Default

    Edit to the above post:

    Since the system() command writes the output of the executed shell command straight to the output buffer, if you wish to hide the return of the command (i.e. "The command completed succesfully" or an error message) from a web browser, you need to alter the command that is sent to the shell so that the output of that command is hidden.

    In the Windows command shell, this is done by sending both the output (1) and error (2) messages to "nul" using pipes, in other words...

    Code:
    // Define parameters for shell command
    $letter = "Z";
    $location = "\\servername\sharename";
    $user = "USERNAME";
    $pass = "PASSWORD";
    
    Execute the command
    system("net use " . $letter . ": \"".$location."\" ".$pass." /user:".$user." /persistent:no>nul 2>&1");
    This differs drastically from the line above - you should be able to just take this code and put your value into the variables. The important bit is the >nul 2>&1 at the end.

    Check out ss64.com for a great page on Windows command redirection and some more great reference pages for various languages.


    As a further side note, I have successfully used either file_exists() or is_dir() to dynamically choose which drive letter to use (file_exists() doesn't always work in IIS/PHP4 for a reason I haven't yet figured out). Here is the function, with code, instructions and examples.
    Last edited by DaveRandom; 04-18-2009 at 07:48 PM. Reason: Additional Informtion

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •