try it now

Encoding Symfony with SourceGuardian

Home / Encoding Symfony with SourceGuardian

Do you need to encode a Symfony 2+ project?

 
(The article was updated for up to Symfony 5.2 but the solution must work for newer versions too)
 
Symfony php framework 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 php scripts does not work out of the box. 
 
We, at SourceGuardian Ltd, used a Symfony default project and encoded the src directory for a test
(available for downloading as zip archive or by using composer from http://symfony.com/download)
 
After running the tests we found that it does not work out of the box with encoded files but we have done a thorough investigation and can give you a recipe. We are not experts in Symfony and do not use it in our work, so what we suggest may not fully correspond with the concept of Symfony engine. However, we sure this gives an idea of what happens and ways for solving the problem. SourceGuardian php encoder can help you.
 
A general problem with Symfony is that it parses source files. We were surprised to found that they do use Reflection API for reading annotations but they also still parse source code for detecting classes. Frankly, this looks as a weird combination.  We also found that Symfony uses token_get_all() in some other parts of the code, which means the solution below may not be enough and require further updates.
 
We developed two possible ways of fixing the issue and running protected files with Symfony. The first is a quick and working solution that needs a small modification to Symfony engine and also it needs doing some modifications of annotations in your custom controllers files.
 
1) At first, we had to change how Symfony detects that a file contains a class. If you take a look at the findClass() method in AnnotationFileLoader class (vendor/symfony/routing/Loader/AnnotationFileLoader.php), you'll see that they tokenize source code and search for 'namespace' and 'class' keywords. Obviously, this cannot work for encoded files. So the idea is to change this to a direct filepath-to-classname mapping. This will work as Symfony insists on using coding standards for file names, class names and how files are arranged in the folders. 
 
Edit AnnotationFileLoader.php and add a new private function:
 
private function findClassInPath($path) {
if ($path[0] == DIRECTORY_SEPARATOR) $path = substr($path, 1);
$className = str_replace(DIRECTORY_SEPARATOR, '\\', str_replace('.php', '', $path));
while(true) {
if (class_exists($appClassName='App\\'.$className)) return $appClassName;
if (class_exists($className)) return $className;
if (($p = strpos($className, '\\')) === false) return false;
$className = substr($className, $p+1);
}
}
 
Then edit the findClass() method and add the following line at the top of the method's code. By doing this we bypass code parsing and use filepath-to-classname mapping:
 
protected function findClass($file)
{
    if ($className = $this->findClassInPath($file)) return $className;
......
 
The change lets Symfony detect encoded class file without parsing it like this:
 
src/Controller/MyController.php -> \App\Controller\MyController
 
src/Acme/DemoBundle/Controller/DemoController.php -> \Acme\DemoBundle\Controller\DemoController
 
It also means the namespaces of your classes must match file paths in src/ folder for this solution to work. Additionally we are looking for  App\ namespace classes located directly in src/ If you use other namespace or namespaces than App\ and your files are not located according to the above rules, you may change the above findClassInPath() method accordingly to make it find your classes.
 
 
2) You also need to change short annotations in your controllers to full ones. We did this change in Acme/DemoBundle/Controller/DemoController.php
 
// import the "@Route" and "@Template" annotations
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
 
Change short annotations:
 
/**
  * @Route("/", name="_demo")
  * @Template()
  */
 
 
To their long equivalents:
 
/**
  * @Sensio\Bundle\FrameworkExtraBundle\Configuration\Route("/", name="_demo")
  * @Sensio\Bundle\FrameworkExtraBundle\Configuration\Template()
  */
 
or since Symfony 5.2
 
/**
  * @Symfony\Component\Routing\Annotation\Route("/", name="_demo")
  */
 
Please note, there may be other annotations in your code and they should be also changed to the full version, e.g. @Security in SecuredController.php demo file.
 
 
You may also want to clear the cache before running:
 
var/cache/*/Container*
 
 
After that you may encode updated controller files as usual and run the application. (Make sure you have a SourceGuardian loader installed in php.ini) Please note, that the above changes do not break compatibility with unencoded code. The unencoded code will run without problems.
 
It's no need to encode any standard Symfony files. Do not encode them. They are open source and encoding them adds delays but will not make your application more protected.
 
We fully understand that the above is not an ideal solution as it requires both changing of the engine and changing of custom files. But that was a quick solution we developed. We also have an idea of making a smarter fix that will allow encoding of Symfony (and probably other engines too) files without any manual modifications of the code. Please bear with us as it will take some time to develop and test it. We are going to make it available on our website soon. 
 
Kind Regards
 
Alexander Belonosov
Senior Developer
SourceGuardian

Support Area

If you have any questions, please fill out our support form. Also, keep an eye out for our new instructional videos which are coming soon.
View Support Area

SourceGuardian

UK Office
 
Office S14
Tanfield Lea Business Centre
Stanley
County Durham
DH9 9DB
United Kingdom
 
USA Office
 
2880 Zanker Road
San Jose, California 95134
United States


"I have been using SourceGuardian for over a year now and wouldn't be without it"
Matthew Levens, http://www.actrix.co.nz
Try our free php source code demo
TRY SOURCEGUARDIAN FREE FOR 14 DAYS
Account Login:

login Forgotten Password?
Connect with us
Bookmark
facebook linkedin twitter rss
© Copyright 2002 - 2021 SourceGuardian Limited
Privacy Policy l Terms & Conditions l Company Info l Contact us l Sitemap l PHP Weekly News