PHP Frameworks compatibility
1. Laravel Support
Encoding of Laravel projects is fully supported. You may encode PHP files of your Laravel project and run them encoded out of the box. Normally, you will want to encode your own PHP files from app/, database/ and routes/ and configuration files from config/. And you don't need to encode any files from vendor/ folder as they are open source, however, you may encode some of them too if necessary.
Please note, that some of the folders within Laravel project contain not only PHP files but also other files which may not be encoded by SourceGuardian. E.g. you may find .css and .js in the public/ folder. If you use GUI it's already configured to encoded only .php and .html as PHP scripts and skip files of other types. However, if you encode from the command line, make sure you add -f"*.php" option to your command to enable encoding only of .php files.
Laravel web page templates (known as blade templates) are not PHP and therefore they may not be encoded out of the box. But as you know, Laravel compiles blade templates to PHP scripts which are then executed directly by PHP engine. Also Laravel looks for .php files at first in resources/views and only then it looks for .blade.php ones. This means that it's possible to pre-compile all of the blade templates to .php and put them to resources/views instead of the original .blade.php. Pre-compiled templates may be encoded by SourceGuardian as normal PHP-scripts.
Laravel is normally adding compiled files to the cache folder and uses a hash value for naming them. If you want to protect your blade templates, we don't need caching of them anymore. You may use this script
to pre-compile all of your blade templates and replace .blade.php with .php version of them in resources/views. Original files will be backed up to another folder. Please read the comments in the beginning of the script before you use it.
1) backup your project
and copy precompileblade.php to the root of your Laravel project
3) read the comments in precompileblade.php and check and update source and backup folders for your .blade.php files
4) run precompileblade.php from the root folder with PHP CLI and check the output for any errors
5) add resources/views to your SourceGuardian project tree
6) encode as usual along with other .php files already added to the project
Pre-compiling should be done only once as part of your encoding process. If you use the command line encoder, you may integrate the script with your deployment shell/make/etc script.
If you use the command line encoder, make sure you added -f"*.php" option to the command line.
If you have any comments or questions on using SourceGuardian for encoding Laravel projects, or if you actually have any questions about SourceGuardian, please feel free to email us to firstname.lastname@example.org
2. Symfony 2+ and SourceGuardian
Symfony is intensively using annotations. Also it detects custom classes by doing source code parsing. While Reflection API is used for getting annotations and that part works perfectly with encoded files, tokenizing of source files and searching for 'namespace' and 'class' keywords is also used. It's obvious that neither of the keywords can be found in the scripts after encoding. That's why running of the encoded Symfony projects does not work out of the box.
We have developed a solution that lets run Symfony encoded files but it requires some minor modification of Symfony engine and also needs some changes in annotations in your code. It's a simple fix but still it's a modification of the code. We are happy to share it if you need a quick solution, please feel free to read a full article
Although the fix tends to work we do not like it. We are working on a more elegant and universal method of encoding and running Symfony encoded files that will not require any modifications of the source code or engine. Please bear with us. We are not using Symfony in our work and we are not experts in it but we still appreciate importance of the fix since Symfony is one of the most popular PHP frameworks.
Once the updated solution is ready we'll refresh this FAQ and also add a blog post about it.
3. Symfony 1.x and SourceGuardian
By default Symfony 1.x excludes encoded files from autoloading. This happens because when Symfony 1.x is looking for classes and reading the contents of files it cannot find class definitions within encoded files. Encoded files do not contain any readable class or interface directives.
Your files may still work after encoding but only until you clear the cache in Symfony. A typical error you can get after encoding the files and clearing the cache is "Fatal error: Class '...' not found in..."
There is a way to fix that. You need to do that before encoding your files.
1) Create config_handles.yml file and put it in the project config folder (sf_root_dir/config)
3) Edit setup() in ProjectConfiguration.class.php file located in the project config folder and add the following line before $this->enablePlugins() that is already there
4) Clear cache by running 'symfony cache:clear' in your project home
5) Run your unencoded project. If you already encoded the files, temporary restore to unencoded copies. Your project should run as usual.
6) Encode your files, clear cache and run your project again. There should be no error messages now. Do not forget to include the newly created cache/sourceguardian/classMapping.txt file when deploying your encoded project.
The sgsfAutoloadConfigHandler class creates an additional PHP 'class to file' mapping and stores it in cache/sourceguardian/classMapping.txt file. The file is automatically updated when you run unencoded files. When you finally encode the project, clear Symfony cache and its standard class mapping configuration cannot be used anymore, the sgsfAutoloadConfigHandler class starts using the previously saved class mapping from the classMapping.txt file.
This works similar to standard Symfony 1.x method of caching class names but in comparison to Symfony it is not cleared with other cache and uses relative file paths (Symfony uses absolute paths). As a result if you distribute the classMapping.txt mapping file along with your encoded files, they will run from the new location and a Symfony new cache can be correctly recreated.
4. Can I encode a WordPress plugin?
Yes. There are some simple rules for successful encoding of WordPress plugins.
- Encode all PHP files, even if they are templates with mostly HTML.
- Do not encode the files that have comments that WordPress requires, such as plugin headers.
- Be sure to exclude any .svn, .git etc folders from the project.
- Turn off encoding for PHP4 in project settings.
- You still need to install an appropriate loader to the server in order to run protected files.
(Thanks to Sean Conklin for the comments about WordPress plugins encoding and testing)
5. Need to encode phar?
If you are using phar and want to encode it or encode some of the files within your phar with SourceGuardian, there are two simple rules to follow:
1) Do not encode the entire phar file. Encode files you add to phar.
2) Do not encode a stub script if you use your own or use standard stub.
6. Nette (PHP framework) and SourceGuardian
We do not use Nette ourselves but similar to the other top-rated PHP frameworks such as Laravel and Symfony we checked Nette for compatibility. A short answer is "it works" but with some modifications.
0) Nette parses PHP sources. You may easily check this by searching for 'file_get_contents' and 'token_get_all' in vendor/nette. This is not a good approach as source code must remain source code with its formatting and comments and that's only PHP engine's job to parse it. There is a definite programming language syntax and any attempts to extend it with "annotations" or other texts added comments and then parsed is not a good idea either.
1) The other thing Nette does is using both RobotLoader and Composer for autoloading. RobotLoader is not compatible with any bytecode encoders because it again(!) parses source files. You may also have your own reason to get rid of RobotLoader and use only Composer and that's a good idea. There is a good article about it
which describes the process in details and worth reading. It may vary slightly because of different namespaces and classes you use in your real project but the main idea is clear.
a) edit composer.json and add the new autoload psr-4 section for the classes you are going to encode. We tested with a nette/web-project sample and added this
b) disable RobotLoader in app/config/config.neon by adding
and also by commenting RobotLoader in app/bootstrap.php
We recommend that you remove RobotLoader from composer.json at all and run
for sure. Otherwise you may simply run
to reload autoloading
It's a good idea the check your unencoded code works as expected after the above changes. Debug if necessary.
2) Nette will still try to parse and read the type information *from source* at some point, so you also need to edit your RouterFactory.php and other files your need to encode and change the namespace in @return definitions to an absolute one. It's absolute in fact.
E.g. change this in RouterFactory.php in createRouter()
to an absolute namespace (note a slash added)
3) Encode app/*.php with SourceGuardian. It's no need to encode Nette itself or other files in vendor/ folder, they are open source.
We successfully encoded and run a sample nette/web-project application after the above changes. Please note, you may need to adapt the above recipe for your project. If you have any questions or comments, please feel free to contact us in support
7. I use a PHP frameworks and got an error on running encoded files
While most of PHP frameworks (their latest versions!) work no problem with encoded files, there are some points to check if you still get a problem:
* Please check you are using the latest version of the framework. While older versions may work, latest version have better support and better compatibility with SourceGuardian. If you ask us to check if something is wrong and you use a PHP framework, we will use the latest version of it.
* Please check you are using the latest version of PHP - its base version X.Y according to your needs but the maximum minor version. Check the framework is compatible with that version of PHP.
* Make sure you encode only PHP files and not encoding templates, documentation, HTML or any kind of various configuration files which may be used by the framework or your project.
* Finally, please check the framework you're using is not trying to parse PHP files in an attempt of extracting any further info from the source code - this won't work for encoded files for obvious reasons! However, using Reflection API and doc comments via Reflection or attributes introduced in PHP 8 are standard ways of adding and using additional information into/from source code. All these standard ways do work with encoded files. You may ask framework developers or community, if you are not sure about such internal facts of how the framework works. Note, some of the frameworks reuse other packages for variuos internal tasks, and while some of them may use new ways of getting additonal info from the source code, the others may still try to parse PHP files.
8. must be of type int, float given
If running a test returns "must be of type int, float given" SourceGuardian encoder converts any integers greater than 2^31 to floats for compatibility with 32-bit system and loaders. Otherwise you'd have to encode separately for 32-bit and 64-bit system your clients might use because of different bytecode. Normally, this does not cause any issues when running the code.
If your code uses very large integer calculations and losing precision, consider using specific libs for this instead - this is what you'd do for 32-bit systems.
You may ignore this error on running your tests, remove type declaration (the easiest) and let PHP work on the internal type, or change the test.