Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Lvkz's avatar
Level 7

Extend the "compile" function on BladeCompiler.php

Hello all, Due to my boss requirements, I need to encrypt our Laravel App, I've tried ZendGuard and IONCube and both do a pretty decent job encrypting the app without breaking Laravel. However, I have an issue with the blade files if I encrypt them, the blade code appears as is, and the reason of that is because 'Blade' is not proper PHP but a Laravel interpreted code.

My workaround so far has been not encrypting the views file but, that is a "security risk" from my boss' perspective. So I researched and found a fix provided by the IONCube guys: edit this file: vendor/laravel/framework/src/Illuminate/View/Compilers/BladeCompiler.php and add a verifier.

public function compile($path = null) {
        if ($path) {
        $this->setPath($path);
        }

        if (! is_null($this->cachePath)) {
        if(function_exists('ioncube_read_file')) {
            //This is what I'm adding.
                    $contents = $this->compileString(ioncube_read_fule($this->getPath()));
                } else {
            //This is the original line.
                    $contents = $this->compileString($this->files->get($this->getPath()));
                }

                $this->files->put($this->getCompiledPath($this->getPath()), $contents);
        }
 }    

It works, but I know that modifying the 'vendor' files is not a very good practice, so I wanted to implement the solution within the app, so my question is: How can I extend the compile function to add the ioncube verification?

0 likes
4 replies
tykus's avatar
tykus
Best Answer
Level 104

One option:

You can define your own ViewServiceProvider which extends the Laravel one. You would then need to override the registerBladeEngine method - this is where the Blade Compiler is bound into the container:

public function registerBladeEngine($resolver)
{
    $this->app->singleton('blade.compiler', function () {
        return new MyBladeCompiler(
            $this->app['files'], $this->app['config']['view.compiled']
        );
    });

    $resolver->register('blade', function () {
        return new CompilerEngine($this->app['blade.compiler']);
    });
    }

MyBladeCompiler extends the Laravel BladeCompiler and overrides the compile method with your implementation.

Finally, swap the Illuminate\View\ViewServiceProvider::class out of the config/app.php providers array, and replace it with your own ViewServiceProvider.

4 likes
Lvkz's avatar
Level 7

@tykus Thank you very much!! Your insight led me to the solution of my problem.

I did the following:

  1. Created a new service provider with php artisan make:provider ViewServiceProvider and filled the provider with the register data. (I had to copy ALL the contents of the Illuminate\View\ViewServiceProvider class, @tykus if you know how can I avoid that, would be great)

  2. Created a class called customBladeCompiler, extending the original BladeCompiler.php and overrided the compile method like this:

class customBladeCompiler extends BladeCompiler {
    /**
     * Compile the view at the given path.
     *
     * @param  string $path
     * @return void
     */
    public function compile($path = null) {
        if ($path) {
            $this->setPath($path);
        }

        if (!is_null($this->cachePath)) {
            if (function_exists('ioncube_read_file')) {
                $contents = $this->compileString(ioncube_read_file($this->getPath()));
            } else {
                $contents = $this->compileString($this->files->get($this->getPath()));
            }

            $this->files->put($this->getCompiledPath($this->getPath()), $contents);
        }
    }
}
  1. Swaped the Illuminate\View\ViewServiceProvider::class out of the config/app.php providers array, and replaced it with my own ViewServiceProvider:
        //Illuminate\View\ViewServiceProvider::class,

        /*
         * Custom View Service Provider
         */

        App\Providers\ViewServiceProvider::class,
tykus's avatar

@Lvkz you can extend the Laravel ViewServiceProvider as I mentioned in the original reply, then you only need to implement/override your custom method(s). This is exactly what you have also done with the BladeCompiler.

This should be the entire contents of your ViewServiceProvider

namespace App\Providers;

use Path/To/MyBladeCompiler;

class ViewServiceProvider extends \Illuminate\View\ViewServiceProvider
{
    public function registerBladeEngine($resolver)
    {
        $this->app->singleton('blade.compiler', function () {
            return new MyBladeCompiler(
                $this->app['files'], $this->app['config']['view.compiled']
            );
    });

    $resolver->register('blade', function () {
        return new CompilerEngine($this->app['blade.compiler']);
    });
    }
}
Lvkz's avatar
Level 7

@tykus Oh, that was dumb of me... Heheheh... Thank you very much!!! It worked like a charm!!!

Please or to participate in this conversation.