|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2019-02-07 22:03 UTC] memso at memso dot net
Description:
------------
Attempting to use the ssh2.sftp stream methods to access files with a hash (#) in the file name always fails.
This seems to occur with all file stream methods. I've tried stat, fopen and is_file, all act like the file does not exist.
Removing the # or changing it to another character fixes the problem, but I do not have control over a remote SFTP I am downloading from and cannot download their files which have a # in the file name.
Test script:
---------------
// Assuming a file named "Some#Test.txt" exists
$ssh2 = ssh2_connect("server", 22);
$sftp = ssh2_sftp($ssh2);
print_r(stat("ssh2.sftp://" . intval($sftp) . "/Some#Test.txt"));
Expected result:
----------------
Results for the "Some#Test.txt" file are expected.
Actual result:
--------------
"false" is output instead
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 23:00:01 2025 UTC |
I've not seen intval() used on a resource like this. Should that work to allow the ssh2.sftp stream wrapper to connect to the server? Have you tried using ssh2_sftp_stat() instead? For example: print_r(ssh2_sftp_stat($sftp, 'Some#Test.txt')); That works for me, though I was able to reproduce your particular issue, using the ssh2.sftp stream wrapper. I don't think this is a bug. stat() uses URL wrappers, and a hash mark in URLs is the start of a fragment, so I think this behaves as expected. To Reproduce Results: --------------------- Start a Docker container for a local SFTP server: docker run --rm -v "${PWD}/files:/home/foo" -p 2222:22 -d atmoz/sftp:alpine foo:pass:1001 Then create the following files in ${PWD}/files: touch files/foo.txt touch files/"Some#Test.txt" Now, run the following script. It'll try to stat each file twice. Once with ssh2_sftp_stat() and once using stat() with the ssh2.sftp stream wrapper. Note how everything succeeds except the last stat() for Some#Test.txt. <?php $ssh2 = ssh2_connect('127.0.0.1', 2222); if (ssh2_auth_password($ssh2, 'foo', 'pass')) { $sftp = ssh2_sftp($ssh2); print_r(ssh2_sftp_stat($sftp, 'foo.txt')); print_r(ssh2_sftp_stat($sftp, 'Some#Test.txt')); print_r(stat('ssh2.sftp://foo:pass@127.0.0.1:2222/foo.txt')); print_r(stat('ssh2.sftp://foo:pass@127.0.0.1:2222/Some#Test.txt')); } else { echo 'Could not authenticate.' . PHP_EOL; }> I've not seen intval() used on a resource like this. Should that > work to allow the ssh2.sftp stream wrapper to connect to the > server? It's document this way in the manual[1], and relies on resource to int conversion to give the unique resource number[2]. > I don't think this is a bug. ACK. The hash mark has to be properly escaped: print_r(stat("ssh2.sftp://" . intval($sftp) . "/Some%23Test.txt")); [1] <http://php.net/manual/en/function.ssh2-sftp.php#refsect1-function.ssh2-sftp-examples> [2] <http://php.net/manual/en/function.ssh2-sftp.php#refsect1-function.ssh2-sftp-examples>@ cmb@php.net Your solution does not work. If the SFTP code is supposed to convert URL encoded strings back to real strings before accessing files, it is not doing so. To make it very clear what is happening, I created 2 files on the SFTP. Some#Test.txt Correct file Some%23Test.txt WRONG FILE When I run the following code: $ssh2 = ssh2_connect("server", 22); $sftp = ssh2_sftp($ssh2); print_r(file_get_contents("ssh2.sftp://" . intval($sftp) . "/Some%23Test.txt")); The result is: WRONG FILE