peachpie icon indicating copy to clipboard operation
peachpie copied to clipboard

include not working when file was not compiled

Open kripper opened this issue 4 years ago • 17 comments

include("test.php") is not processing the PHP tags when "test.php" was not compiled into an assembly. The PHP source code is dumped as is.

We are testing latest peachpie version.

Use case: The application mixes compiled php files which include other source (not compiled) php files that are created/modified after the application has been deployed.

Is this supported? if not, I guess it could be implemented using something similar as the implementarion of eval().

Congratulations for the good work.

kripper avatar May 18 '20 05:05 kripper

Yes, currently it is by design, so all the code has to be compiled in advance.

Internally, developers can use eval() with caution; it does not respect autoload and most of the possible optimizations won't work.

jakubmisek avatar May 20 '20 20:05 jakubmisek

Thanks. Can this feature be added in Peachpie using the same strategy used in Phalanger.

BTW, we updated Phalanger to the last commit before the "invalid dynamic wrappers format" bug was introduced (when the assembly names changed) and it's working fine on Linux. It seems that the build environment also changed to Visual Studio 14 (?). Amazing project!. We would love to migrate to Peachpie.

kripper avatar May 20 '20 23:05 kripper

Is it possible to set the Peachpie "PHP handler" in web.config and reference a compiled assembly from .php files?

Use case: you need to provide a customer the ability to change some source .php files without having to recompile all resources.

kripper avatar May 20 '20 23:05 kripper

This is not a part of peachpie since it would break all the compiler and runtime optimizations. In case you need changing source files during run time, you have to be sure the changed files are not a dependency to other code blocks or types, then you can implement your handler and eval' the changed file.

Usually if you need to be able to change source files during run time, it is some sort of configuration which is always better to put into a json file, not a source file.

jakubmisek avatar May 25 '20 20:05 jakubmisek

Just to make sure I explained correctly, the use case is NOT changing PHP files while running (JIT compiling), but to deploy a .dll library (compiled code) together with .php files (source code). If the .php file is changed, it's ok if the .php file is recompiled and the web app resarted.

Currently, when we deploy a .dll together with .php files, Phalanger recompiles the modified .php file and the web app is resarted.

I believe Peachpie also supports a PhpHandler that recompiles the .php files when they are modified, and I guess Peachpie also supports adding assemblies in web.config exposing methods that can be called from .php files, right?

Thus, if this all above is correct, we could deploy our app with Peachpie's PhpHandler, call methods defined in the .dll library and this way satisfy this use case.

kripper avatar May 25 '20 22:05 kripper

yes, see above

jakubmisek avatar May 25 '20 23:05 jakubmisek

in case you need to recompile the project after source files change, you have to recompile it after your source files change:

dotnet build

or

dotnet watch run

peachpie does not compile source files by itself, nor phphandler, nor web.config

jakubmisek avatar May 25 '20 23:05 jakubmisek

I see. That means Peachpie's phphandler is just interpreting but not compiling right?

In the case of Phalanger, when you call include() from a Multi Script Assembly, it checks if the .php file exists and compiles it, right?

kripper avatar May 25 '20 23:05 kripper

afaik; Phalanger did watch for source files changes (that means it required you to have all the sources deployed with the DLL's), it kept map of dependencies between source files, and recompiled everything upon request.

Phalanger != PeachPie (that's why it has a different name).

PeachPie disallows having source files deployed on server, it ignores them, it ignores their changes (watching for timestamps is done by msbuild), and lets you compile the project when you consider it is needed. This is on purpose and by design.

jakubmisek avatar May 26 '20 12:05 jakubmisek

I'd like to ask for a reason why PHP files can't just be compiled on demand like... well... every other framework?

wasabii avatar Jul 19 '20 16:07 wasabii

@wasabii "every other" is currently only Zend PHP.

PeachPie is ahead-of-time compiler. It needs to know the whole project in order to generate a valid and reasonably efficient .NET assembly. For the future major version (after the upcoming release), we are planning to compile files on the fly (through a mechanism similar to eval). Currently, it is a very complex feature that we'd like to do after all the other important things are working.

jakubmisek avatar Jul 19 '20 17:07 jakubmisek

Well, by "every other", I mean ASP.NET itself. You can drop in Razor files and it's fine. But also, previous .NET frameworks. You can drop in aspx files, and it's fine.

I figured you'd just do the same as them: keep an index of path name to assembly and entry point method, and then resolve them from a lazy cache at runtime, compiling as you go.

wasabii avatar Jul 19 '20 17:07 wasabii

Yes, you are right. In the .NET world, it is done by running the compiler during the run time. We'll do the same once the rest of the features will be stable.

jakubmisek avatar Jul 19 '20 19:07 jakubmisek

Maybe one simple solution is to make Peachpie compile all .php files inside the webapp folder to a .dll library (in the same way it is done via "dotnet build") and then reference this .dll inside the web.config file or equivalent. This way, we won't be doing an ugly eval and having all optimizations. I guess ASP.NET framework also provides some configuration to trigger the "dotnet build" process when a source file is changed.

kripper avatar Jul 25 '20 22:07 kripper

@kripper take a look on dotnet watch

jakubmisek avatar Jul 25 '20 22:07 jakubmisek

I believe this feature is also important for "config" file designs where the config file looks like this:

<?php
return [ 'foo' ];

which is then later loaded into an array with:

$config = require 'config.php';

This is for example the typical case for config files used in the Laminas framework.

matbech avatar Nov 21 '20 05:11 matbech

@matbech that's right. Usually we implement this specifically for this given framework in C#

  • either watching for the file changes and then re-compiling that single file in-memory (using Roslyn scripting API, class PhpCompilation)
  • or slightly changing this configuration file to something like:
    <?php return json_decode(file_get_contents('config.json'));
    

Although I understand if it would behave the same as in PHP it would be much easier for transition

jakubmisek avatar May 12 '21 07:05 jakubmisek

Closing. Source files don't auto-compile by design. dotnet watch may be used instead.

kripper avatar Mar 15 '23 19:03 kripper