0

I have two files: one called AB.txt, the other called A&B.txt. For each, I run the following PHP code:

echo "[$arq]";
if (file_exists($arq)) {
    echo '[found]';
} else {
    echo '[none]';
}

The outputs are [AB.txt] [found] and [A&B.txt] [none].

I tried replacing the & with \& inside file_exists(), but it also doesn't work. And it doesn't seem to be a (lack of) UTF-8 problem.

Why is that? I'm on a Linux (Debian 11) machine, using PHP 7.4.

EDIT

var_dump(scandir('.'));

Returns hundreds of files (they're on a subdirectory, actually, but let's pretend they're not). I've removed all the other files from the list bellow.

array(352) { [302]=> string(7) "A&B.txt" [303]=> string(6) "AB.txt" }

EDIT 2

var_dump($f = "diffA&B.txt", file_exists($f), touch($f), file_exists($f));

string(11) "diffA&B.txt" bool(false) bool(true) bool(true)

Rodrigo
  • 4,706
  • 6
  • 51
  • 94
  • How do you set the value for `$arq`? What is the output of `var_dump($arq);` when you use the filename `A&B.txt`? – Progman Oct 24 '22 at 21:49
  • @Progman $arq comes from $_POST. var_dump gives `string(7) "A&B.txt"` – Rodrigo Oct 24 '22 at 21:54
  • try to use scandir method and check the existance with in_array() – Khaled Hassan Oct 24 '22 at 21:54
  • @KhaledHassan Thank you. I can use glob too, but I want to find out why file_exists doesn't work here. – Rodrigo Oct 24 '22 at 21:56
  • @Rodrigo Please [edit] your question to include the output of `var_dump($f = "diffA&B.txt", file_exists($f), touch($f), file_exists($f));` to your question. Be careful with the filename here, I used a different one so it is not in a conflict with your current file, but for obvious reason, it should still contain a `&`. Delete any such file before running the new code (any followup execution will return `true` for the first `file_exists()`). – Progman Oct 24 '22 at 22:10
  • @Progman Edited. Strangely, now it recognizes the newly created file. – Rodrigo Oct 24 '22 at 22:14
  • I just tried this and it worked fine. Are you on Unix or Windows? – Barmar Oct 24 '22 at 22:35
  • @Rodrigo Check the bytes in the string `$arq` and check the bytes of the array entry `[302]` from the `scandir('.')` call, see https://stackoverflow.com/questions/14674834/php-convert-string-to-hex-and-hex-to-string – Progman Oct 24 '22 at 22:47
  • The more pertinent question is: What OS are you using, and what filesystem are these files on? – Sammitch Oct 24 '22 at 22:52
  • @Barmar Linux (Debian 11). It's on the question. – Rodrigo Oct 24 '22 at 23:00
  • @Sammitch Linux (Debian 11). It's on the question. The filesystem is Ext4 (version 1.0). – Rodrigo Oct 24 '22 at 23:01
  • @Progman `A&B.txt` is not the real filename. I just used it to simplify things. `bin2hex("A&B.txt")` returns `4126422e747874`, with `26` as the hex for `&`. While the real file name (in `$arq`) returns `26616d703b` in the place where the `&` is. `hex2bin('26616d703b')` returns `&`, which appears as a single `&` under `echo`, etc. So it seems you pinpointed the source of it. Thank you! – Rodrigo Oct 24 '22 at 23:15
  • @Progman Problem solved. I was using `.innerHTML` before submitting the form (thus `&` became `&`), where I should use `.innerText`. – Rodrigo Oct 24 '22 at 23:32
  • 1
    @Rodrigo For the future: Do not change any requested debug information. The `var_dump()` line shows the length and content of a string and if you have showed the real output, it would be easily visible that the string length does not match the visible string content. – Progman Oct 25 '22 at 16:31

0 Answers0