This is my first post and I couldn't decide if this should go into the PHP5 forum so I apologize if my post is misplaced. Let me know and I'll move it.

Some Background:

I'm basically writing a script to connect to an FTP server and download any new files that I don't already have locally. My goal was to make the code as generic as possible.

One of the first necessary tasks for doing this is to get a list of files/directories from the FTP server. To do this I implemented the SPL Iterator interface and created my own FTPDirectoryIterator class. I also went the next step and extended that class into a RecursiveFTPDirectoryIterator class. The constructor for the iterator accepts an FTP stream resource. And it works great except for one problem:
ftp_rawlist()

Unfortunately I can't handle the problem gracefully because the EXACT issue is that my script will just hang on the ftp_rawlist() command or sometimes ftp_rawlist() returns an empty array. I was able to come up with a 'hack' solution to the empty array issue by looping the ftp_rawlist() call 3 times (seems to always work the second time it's called which is wierd) but if it hangs, I'm hosed and the script times out. This is NOT consistent. Sometimes it works and sometimes it hangs. There is no method to the madness.

Researching this in these forums and on the internet I see that ftp_rawlist() and ftp_nlist() have been a problem in PHP for a while.

What I've Already Tried:

  • I tried ftp_nlist() with the same issues.

  • I tried a quick inline approach for debugging, seeing if I could get ftp_rawlist() to hang. I couldn't, which makes me wonder if my OOP approach utilizing the SPL Iterator interface might somehow be causing this???

  • I've verified that my FTP resource that I'm passing to ftp_rawlist() is valid every time.

  • I tried different passive mode on/off. ftp_rawlist() seems to work more often with passive mode off, which I thought was strange. But it will still hang on occasion regardless.

  • I tried going the ftp_raw() route and passing an 'LS' command. Unfortunately the server returns a 500 error: "command not recognized", which is BS since it's a Unix server and the 'pwd' and 'cd' commands work fine with ftp_raw()... sorry, I got a little upset there... I think the server admins have some remote commands restricted?

  • Online I found a tip that some servers run extended passive mode and to run ftp_exec ($FTPresource, 'epsv4 off'); but I get the old "command not supported" message of doom.

Versions

  • The FTP server I'm connecting to is a Unix server. That's all I know. I got this from the ftp_systype() function.

  • When I run the script locally, I'm running on the Zend Core WAMP (v2.0), and I'm running PHP CLI 5.2.1

  • The devel server I commit to is running LAMP (also Zend Core). I'm executing my script via PHP CLI (5.1.5).
    NOTE: When I run my script on the development server the ftp_rawlist() will still hang but it eventually moves on and my loop 'hack' picks right back up where it should, so it 'sort of' works, but I don't have a lot of confidence in it because ftp_rawlist() still hangs for a good 20 seconds and then throws an error.

Conclusion

Sorry for the long post. I am open to any ideas. Is there another way to get a directory listing from an FTP server other than PHP's FTP functions? Is there a magic call I do to make ftp_rawlist() work properly? Perhaps there is a freeware application that can do what I'm trying to accomplish to automatically synchronize a local server with the files on an FTP server?

I appreciate any help at all.

    Write a Reply...