Why can't PHP find long filenames? - php

inside a Folder I have a file, named
`111-aaaaaa aa aaaa-,._aaaaaaa; aaaaaaaa, aa aaaaaaaaaa, aaaaaaaaa aaaaaaaa. 03.01.10. 38.38 aaaaa.txt`
when I browse that directory with PHP (or trying to read that file):
var_dump(glob('MyFolder/*'));exit;
It can't find that file. What's problem?
(if I shorten the filename, then it becomes findable. I am on windows)

Windows in particular has a very short file name limit in its original Win32 API. This general problem is discussed here at SO.
At most about 260 characters can be used in an absolute path on Win32. On other platforms there are other limits, but at least 512 characters is to be expected and more is not unheard of.
(For instance, in GNU HURD, there effectively is no limit to file lengths, even though the underlying file system may impose a limit.)
However, Windows actually can have longer filenames (obviously, as you have them on your computer). This works by using a newer Windows API. Unfortunately, standard PHP does not use this API, as far as I know.
There is a modified version of PHP which makes use of this newer Windows API over at Github.
Another benefit from using that newer API is that it also supports Unicode characters in the file names.

try scandir()
it's show list file in array.

Starting with PHP 7.1 long and UTF-8 paths on Windows are supported directly in the core.
Cheers.

Related

PHP: Which ZipArchive::EM_ constant to use when encoding ZIP Archive with custom password

I have a question about encoding zip files with password, which is available from PHP v 7.2
When I am encoding ZIP with method
ZipArchive::setEncryptionName
There are argument method which can be:
ZipArchive::EM_AES_128
ZipArchive::EM_AES_192
ZipArchive::EM_AES_256
Can somebody tell me / explain which to use and why?
I am now using ZipArchive::EM_AES_256 because I am expecting that it is the most secure but my colleague is telling me that he cannot open it (his zip software is not even asking for password).
So is there one which will be working in all the cases? We have software which is used by a lot of people in my country and a lot of old people might get these ZIP files and it is required that they could be opened and that every zip file has a password.
Please consider that they might even use Windows XP etc.
As per your comment, Windows cannot decrypt AES-encrypted archives natively, not even in recent versions such as Windows 10 (see why).
PHP v8.0 adds "traditional pkware encryption" that will allow Windows users to work with files without 3rd party apps (7-Zip, etc).
For PHP v7.x, one needs to either rely on shell commands or use a library that supports ZipCrypto encryption algorithm (sometimes called "pkware" - as per the company that created the zip format). Several out of the most popular zip libraries on packagist use ext-zip, so they won't offer PKWARE encryption on PHP 7.x. However nelexa/zip doesn't and it supports pkware encryption.

PHP as independent application ( binary, compile, pack, no php on host )

If I would like to distribute PHP application with installer(package system of OS) how should I proceed? I don't want PHP files to be there, just working application, so when I type 'app' into console, it ends up being launching application, without need to install PHP on system(no php installation on host required). I would also like the application to have patch-able byte-code, so it's in parts, loaded when needed and only part needs to be replaced on update.
What I would do now is following:
->Compile PHP with extensions for specific platform.
->Make binary application which launches '/full/php app' when app is launched.
->Pack it in installer in a way, that there would be binary added to path when added, launching specific installation of PHP which is alongside the app with argument of start point->App would be running.
Problem is:
Maybe I don't want my PHP files to be exposed(in application, there will be available source anyway) is there some ready made stuff to do this? Is there some better way than I proposed?
Alternative: Modifying OP Cache to work with "packing" application to deliver byte codes to modified OP Cache which just reads the cache.
My suggestion would be a tiny tool I just finished, for almost exactly the same problem. (Oh yes I tried all the others but they're old and rusty, sometimes they're stuck with 4.x syntax, have no support, have no proper documentation, etc)
So here's RapidEXE:
http://deneskellner.com/sw/rapidexe
In the classical way, it's not a really-real compiler, just a glorified packer, but does exactly what you need: the output exe will be standalone, carrying everything with it and transparently building an ad-hoc runtime environment. Don't worry, it all happens very fast.
It uses PHP 7.2 / Win64 by default but has 5.x too, for XP compatibility.
It's freeware, obviously. (MIT License.)
(Just telling this because I don't want anyone to think I'm advertising or something. I just took a few minutes to read the guidelines about own-product answers and I'm trying to stay within the Code of the Jedi here.)
However...
I would also like the application to have patch-able byte-code, so it's in parts, loaded when needed and only part needs to be replaced on update.
It's easier to recompile the exe. You can extract the payload pieces of course but the source pack is one big zip; there seems to be no real advantage of handling it separately. Recompiling a project is just one command.
Maybe I don't want my PHP files to be exposed(in application, there will be available source anyway)
In this case, the exe contains your source compressed but eventually they get extracted into a temp folder. They're deleted immediately after run but, well, this is no protection whatsoever. Obfuscation seems to be the only viable option.
If something goes wrong, feel free to comment or drop me a line on developer-at-deneskellner-dot-com. (I mean, I just finished it, it's brand new, it may misbehave so consider it something like a beta for now.)
Happy compiling!
PHP doesn't do that natively, but here are a few ideas:
Self-extracting archive
Many archival programs allow you to create a self-extracting archive and some even allow to run a program after extraction. Configure it so that it extracts php.exe and all your code to a temp folder and then runs ir from there; deleting after the script has complete.
Transpilers/compilers
There's the old HPHC which translates PHP code to C++, and its wikipedia age also contains links to other, similar projects. Perhaps you can take advantage of those.
Modified PHP
PHP itself is opensource. You should be able to modify it withot too much difficulty to take the source code from another location, like some resource compiled directly inside the php.exe.
Use Zend Guard tool that compiles and converts the plain-text PHP scripts into a platform-independent binary format known as a 'Zend Intermediate Code' file. These encoded binary files can then be distributed instead of the plain text PHP. Zend Guard loaders are available for Windows and Linux platform that enables PHP to run the scripts encoded by Zend Guard.
Refer to http://www.zend.com/en/products/zend-guard
I would like to add another answer for anyone who might be Googling for answers.
Peach Pie compiler/runtime
There is an alternative method to run (and build apps from) .php source codes, without using the standard php.exe runtime. The solution is based on C#/.NET and is actually able to compile php source files to .NET bytecode.
This allows you to distribute your program without exposing its source code.
You can learn more about the project at:
https://www.peachpie.io/
You've got 3 overlapping questions.
1. Can I create a stand-alone executable from a PHP application?
Answered in this question. TL;DR: yes, but it's tricky, and many of the tools you might use are semi-abandoned.
2. Can I package my executable for distribution on client machines?
Yes, though it depends on how you answer question 1. If you use the .Net compiler, your options are different to the C++ option.
3. Can I protect my source code once I've created the application?
Again, depends on how you answer question 1. Many compilers include an "obfuscator" option which makes it hard to make sense of any information you get from decompiling the app. However, a determined attacker can probably get through that (this is why software piracy is possible).

Is there php7 printer extension/dll?

Is there any printer extension for php 7 ? Or can someone provide working solution how to print form php? Or I should use sockets for that ? I tried dll from 5.6 but it doesnt work(
There's a lot of stuff to be done to make its source code available for build into an usable extension besides the common tasks. There are some replacements that can be done and other issues involve finding what to do with no longer used variables and currently invalid syntax. It's a a very outdated, yet usefull extension. I've also tried to do it myself with no success (it builds but it doesn't work).
The easiest way I found and still use in POS (receipt) Printers is just a
system("(echo ".$TextToBePrinted.") >\\\\MachineNameOrPreferablyFixedIp\\PrinterNetworkName");
Every time a new line is needed. Null and newLine characters are indeed possible to send in a single command containing whole custom text, but it's very fastidious. For the same kind of printers there is esc-pos php library available.
Note: No matter if it is a local printer, it has to be shared and better if used as "\\127.0.0.1\PrinterNetworkName". PrinterNetworkName avoids invalid characters as same as in files, so "Generic / Text Only" has to be accessed as "\\127.0.0.1\Generic Text Only".
Simmilar alternatives for common use printers include using dosprn and fwrite or, again,system("echo ...");ing to COMn/LPTn faked or real ports or, if you don't care: create, write and system("print ..."); file having correctly associated extension for the filename you gave.
And for the hardcord-ers, you can build a binary (.exe) to listen to a custom port or calling binary with system(...); directly and print. It's no so hard on c++ using boost. The real hardcore decision would be building a dll extension (By the way: C++ windows api contains simmilar functionality for printing like php does in its extension for managing paper and font size, style and so on).
PHP and dll's with different fisrt two numbers in version won't work. So stop trying to make it happen.

Can I compile Ming for PHP/Windows?

Where can I find instructions for compiling Ming? Google is confused and thinks I am looking for pages about MinGW (the C++ lib for Windows) when in fact I want this:
http://www.php.net/manual/en/book.ming.php (a PHP lib for creating SWF files)
I currently have Wamp Server installed. I checked the option php_ming, but Ming still did not work. I finally found out that even though Wamp is adding the right line to the php.ini file, the actual file it refers to "php_ming.dll" does not exist on my computer.
It also does not appear to exist on the Internet (at least not on any safe looking website). So, apparently, I must compile it from scratch. Compiling in C is very difficult for me, because I do not understand why so many different types of files and configuration options are required, which files to get, where to get them, and where to put them.
I get DOT C files (programs) and DOT H files (includes), but I quickly get lost with DOT O files, "linker" files, command line options - and all the specifics which must be exactly right for any compile to work. For this reason, I am looking for instructions on how to compile Ming for PHP/Windows. Where can I find this?

glob() can't find file names with multibyte characters on Windows?

I'm writing a file manager and need to scan directories and deal with renaming files that may have multibyte characters. I'm working on it locally on Windows/Apache PHP 5.3.8, with the following file names in a directory:
filename.jpg
имяфайла.jpg
file件name.jpg
פילענאַמע.jpg
文件名.jpg
Testing on a live UNIX server woked fine. Testing locally on Windows using glob('./path/*') returns only the first one, filename.jpg.
Using scandir(), the correct number of files is returned at least, but I get names like ?????????.jpg (note: those are regular question marks, not the � character.
I'll end up needing to write a "search" feature to search recursively through the entire tree for filenames matching a pattern or with a certain file extension, and I assumed glob() would be the right tool for that, rather than scan all the files and do the pattern matching and array building in the application code. I'm open to alternate suggestions if need be.
Assuming this was a common problem, I immediately searched Google and Stack Overflow and found nothing even related. Is this a Windows issue? PHP shortcoming? What's the solution: is there anything I can do?
Addendum: Not sure how related this is, but file_exists() is also returning FALSE for these files, passing in the full absolute path (using Notepad++, the php file itself is UTF-8 encoding no BOM). I'm certain the path is correct, as neighboring files without multibyte characters return TRUE.
EDIT: glob() can find a file named filename-äöü.jpg. Previously in my .htaccess file, I had AddDefaultCharset utf-8, which I didn't consider before. filename-äöü.jpg was printing as filename-���.jpg. The only effect removing that htaccess line seemed to have was now that file name prints normally.
I've deleted the .htaccess file completely, and this is my actual test script in it's entirety (I changed a couple of file names from the original post):
print_r(scandir('./uploads/'));
print_r(glob('./uploads/*'));
Output locally on Windows:
Array
(
[0] => .
[1] => ..
[2] => ??? ?????.jpg
[3] => ???.jpg
[4] => ?????????.jpg
[5] => filename-äöü.jpg
[6] => filename.jpg
[7] => test?test.jpg
)
Array
(
[0] => ./uploads/filename-äöü.jpg
[1] => ./uploads/filename.jpg
)
Output on remote UNIX server:
Array
(
[0] => .
[1] => ..
[2] => filename-äöü.jpg
[3] => filename.jpg
[4] => test이test.jpg
[5] => имя файла.jpg
[6] => פילענאַמע.jpg
[7] => 文件名.jpg
)
Array
(
[0] => ./uploads/filename-äöü.jpg
[1] => ./uploads/filename.jpg
[2] => ./uploads/test이test.jpg
[3] => ./uploads/имя файла.jpg
[4] => ./uploads/פילענאַמע.jpg
[5] => ./uploads/文件名.jpg
)
Since this is a different server, regardless of platform - configuration could be different so I'm not sure what to think, and I can't fully pin it on Windows yet (could be my PHP installation, ini settings, or Apache config). Any ideas?
It looks like the glob() function depends on how your copy of PHP was built and whether it was compiled with a unicode-aware WIN32 API (I don't believe the standard builid is.
Cf. http://www.rooftopsolutions.nl/blog/filesystem-encoding-and-php
Excerpt from comments on the article:
Philippe Verdy 2010-09-26 8:53 am
The output from your PHP installation on Windows is easy to explain :
you installed the wrong version of PHP, and used a version not
compiled to use the Unicode version of the Win32 API. For this reason,
the filesystem calls used by PHP will use the legacy "ANSI" API and so
the C/C++ libraries linked with this version of PHP will first try to
convert yout UTF-8-encoded PHP string into the local "ANSI" codepage
selected in the running environment (see the CHCP command before
starting PHP from a command line window)
Your version of Windows is MOST PROBABLY NOT responsible of this weird
thing. Actually, this is YOUR version of PHP which is not compiled
correctly, and that uses the legacy ANSI version of the Win32 API (for
compatibility with the legacy 16-bit versions of Windows 95/98 whose
filesystem support in the kernel actually had no direct support for
Unicode, but used an internal conversion layer to convert Unicode to
the local ANSI codepage before using the actual ANSI version of the
API).
Recompile PHP using the compiler option to use the UNICODE version of
the Win32 API (which should be the default today, and anyway always
the default for PHP installed on a server that will NEVER be Windows
95 or Windows 98...)
Then Windows will be able to store UTF-16 encoded filenames (including
on FAT32 volumes, even if, on these volumes, it will also generate an
aliased short name in 8.3 format using the filesystem's default
codepage, something that can be avoided in NTFS volumes).
All what you describe are problems of PHP (incorrect porting to
Windows, or incorrect system version identification at runtime) :
reread the README files coming with PHP sources explaining the
compilation flags. I really think that the makefile on Windows should
be able to configure and autodetect if it really needs to use ONLY the
ANSI version of the API. If you are compiling it for a server, make
sure that the Configure script will effectively detect the full
support of the UNICODE version of the Win32 aPI and will use it when
compiling PHP and when selecting the runtime libraries to link.
I use PHP on Windows, correctly compiled, and I absolutely DON'T know
the problems you cite in your article.
Let's forget now forever these non-UNICODE versions of the Win32
API (which are using inconsistantly the local ANSI codepage for the
Windows graphical UI, and the OEM codepage for the filesystem APIs,
the DOS/BIOS-compatible APIs, the Console APIs) : these non-Unicode
versions of the APIs are even MUCH slower and more costly than the
Unicode versions of the APIs, because they are actually translating
the codepage to Unicode before using the core Unicode APIs (the
situation on Windows NT-based kernels is exactly the reverse from the
situation on versions of Windows based on a virtual DOS extender, such
as Windows 95/98/ME).
When you don't use the native version of the API, your API call will
pass through a thunking layer that will transcode the strings between
Unicode and one of the legacy ANSI or CHCP-selected OEM codepages, or
the OEM codepage hinted on the filesystem: this requires additional
temporary memory allocation within the non-native version of the Win32
API. This takes additional time to convert things before doing the
actual work by calling the native API.
In summary: the PHP binary you install on Windows MUST be different
depending on if you compiled it for Windows 95/98/SE (or the old
Win16s emulation layer for Windows 3.x, which had a very mimimum
support of UTF-8, only to support the Unicode subsets of Unicode used
by the ANSI and OEM codapges selected when starting Windows from a DOS
extender) or if it was compiled for any other version of Windows based
on the NT kernel.
The best proof that this is a problem of PHP and not Windows, is that
your weird results will NOT occur in other languages like C#,
Javascript, VB, Perl, Ruby... PHP has a very bad history in tracking
versions (and too many historical source code quirks and wrong
assumptions that should be disabled today, and an inconsistant library
that has inherited all those quirks initially made in old versions of
PHP for old versions of Windows that are even no longer officially
supported, by Microsoft or even by PHP itself !).
In other words : RTM ! Or download and install a binary version of
PHP for Windows precompield with the correct settings : I really think
that PHP should distribute Windows binaries already compiled by
default for the Unicode version of the Win32 API, and using the
Unicode version of the C/C++ libraries : internally the PHP code will
convert its UTF-8 strings to UTF-16 before calling the Win32 API, and
back from UTF-16 to UTF-8 when retrieving Win32 results, instead of
converting PHP's internal UTF-8 strings back/to the local OEM codepage
(for the filesystem calls) or the local ANSI codepage (for all other
Win32 APIs, including the registry or process).
Try to set internal encoding inside in function (script).
setlocale(LC_ALL,'C.UTF-8');
PHP on windows does not use the Unicode API yet. So you have to use the runtime encoding (whatever it is) to be able to deal with non ascii charset.
Starting with PHP 7.1 long and UTF-8 paths on Windows are supported directly in the core.

Categories