Phalanger
Phalanger copied to clipboard
file_exists() should check MSA libraries
Some PHP apps use file_exists() for checking whether a .PHP file exists or not. For example, for checking if a module is installed, or to find out where it is installed. Even if PHP files are compiled and not on the filesystem, IMO file_exists() should check inside MSA in order to increase compatibility. Does it make sense?
We are considering this behavior, however it would break some apps expecting the file that exists can be read then.
Expecting the php file to be readable makes sense for dumping its source code, but would be less common.
Anyway, if we want maximum compatibility, fopen, file, et. al. should return or open a virtual file with the content "Source code was compiled and is not available."
For now, I would just consider to return file_exists to return true since most of the time it's only for knowing if we can include it or not.
Jakub Míšek [email protected] wrote:
Weareconsideringthisbehavior,howeveritwouldbreaksomeappsexpectingthefilethatexistscanbereadthen.ReplytothisemaildirectlyorviewitonGitHub.
for instance my legacy code read php files. Because of this i publish site precompiled, but with php files
giving "Source code was compiled and is not available" as the file content makes no sense.
file_exists() checks files on file system, it is documented in this way, and doing something else would cause unpredictable behavior.
I can only suggest to extend file_exists() function with a parameter telling to check precompiled assembly as well or to write own function e.g. phalanger_script_exists().
The goal is to increase compatibility (have PHP apps running out of the box), so the default behavior should be in this direction too.
So which pattern is more common? a) file_exists($phpFile) + include($phpFile) b) file_exists($phpFile) + file($phpFile) <--- For dumping source code I guess
I like proff's approach. He is publishing those PHP files besides compiling them. This would solve b) cases. For a) cases, there is no workarround.
We have two options.
-
Asume that a MSA is a package of PHP files that are virtually there, altough not physically...and let file operations work as expected (as if the PHP files were there) and just like without Phalanger.
-
Extend the standard functions (add a second parameter to file_exists() or add Phalanger specific functions).
I believe that, at the end, it would preferable option 1, since we don't want to break compatibility.
Anyway, I need to check if a script is present, ideally from file_exists(). But this function is inside the ClassLibrary, and I don't see no elegant way to get to the ScriptLibraryDatabase.ContainsScript() function inside the Core.
Can you please give me a hint/example to get there from file_exists()?
but with my approach may be other compatibility problems: if file changed then phalanger continue using precompiled version.
Right. I guess the physically (outdated) PHP file, should always overwrite whatever is deployed inside the MSA. This is useful (allows releasing some specific PHP files without recompiling) and less confusing (because you see physically files, while you don't easily see compiled ones).
Anyway, file_exists should be giving true in both cases.
Returning false for a .PHP file even when it is present inside the MSA, is like inconsistent with what include/require statements do.
Jakub, do you know a clean way to check the script library entries from the file_exists function?
proff [email protected] wrote:
butwithmyapproachmaybeothercompatibilityproblems:iffilechangedthenphalangercontinueusingprecompiledversion.ReplytothisemaildirectlyorviewitonGitHub.
@proff precompiled script in MSA should be overiden by new physical file. In addition to that there is an option for not use physical files if there is some in MSA (security reasons)
file_exists should behave strictly as it is documented. We can add some runtime options, but by default any other behavior would be confusing. Also note MSA and precompilation itself is not compatible with PHP in many other ways; if you are using this feature, you should be aware of that. Anyway we are collection suggestions and ideas for upcoming Phalanger update and cleanup MSA and precompilation will be definitely big topic.
BTW why to check for file_exists and then include? Just call include and suppress the warning.
@jakubmisek, i'll check again. May be it was #14
@jakubmisek,
Some scripts use to check if a given PHP file is present, and set a variable for including this and other files (for example, related .js and .css resource does). In my case, I need to include single files from location A (alternative origin, which overwrites B) or location B (default origin) when the file was not present in A, and know which one is present.
A run-time feature configuration is fine (eg: "msaVirtualFilesystem").
If you commit some initial untested code for checking the script library entries (Core) from file_exists (ClassLibrary), I could test/finish the code (with or without the mentioned run-time configuration checking).
I overcame this recently in the unit tests of wikiLingo by simply iterating through the classes returned from get_declared_classes(). So in one situation, I iterate through all the files in a directory to run the tests, and if the files are not available, I do the above. Works fine on both accounts. Code is here: https://github.com/wikiLingo/wikiLingo/blob/master/WikiLingo/Test/TypeNamespace.php
Lines 29-33
Have fun!
Nice, but in my case, the includes don't define classes or functions that could be checked. Another workarround would be to set some variables in the includes, in order to check if they exist and find out this way if the included file exists in the MSA. Anyway, I would prefer file_exists() also to check the existence of compiled includes in order to keep compatibility with original PHP applications, without the necessity to modify them to support Phalanger.