I am facing a strange issue in the interaction between a view and ZipArchive in laravel. I made some test class to test the issue:
<?php
namespace AppServices;
use ZipArchive;
class Test
{
public static function zipTest()
{
$zip = new ZipArchive();
echo "zipped";
}
}
When I call the function through the console via a dedicated command I made, php82 artisan command:test
, there is no issue and AppServicesTest::zipTest()
; executes just fine:
<?php
namespace AppConsoleCommands;
class TestBase extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'command:test';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Test some code';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
AppServicesTest::zipTest();
}
}
php82 artisan command:test
zipped
However when I call AppServicesTest::zipTest()
; in a blade, I get the error Class "ZipArchive" not found.
<div>
@php
AppServicesTest::zipTest();
@endphp
hello!
</div>
The server running the application has several versions of php running, the one used for the application is 8.2.20 (php82
). I had to request the admin to install the php zip functionality and they told me they installed the php82-php-pecl-zip
package.
The version of laravel is v10.16.1.
Can you help me figure out what is going on?
Full error message if it helps:
local.ERROR: Class "ZipArchive" not found {"view":{"view":"/home/photodb/gabriel/resources/views/test.blade.php","data":[]},"userId":1,"exception":"[object] (SpatieLaravelIgnitionExceptionsViewException(code: 0): Class "ZipArchive" not found at /home/photodb/gabriel/app/Services/Test.php:11)
[stacktrace]
#0 /home/photodb/gabriel/resources/views/test.blade.php(11): AppServicesTest::zipTest()
#1 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php(124): require('...')
#2 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php(125): IlluminateFilesystemFilesystem::IlluminateFilesystem{closure}()
#3 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/View/Engines/PhpEngine.php(58): IlluminateFilesystemFilesystem->getRequire()
#4 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/View/Engines/CompilerEngine.php(72): IlluminateViewEnginesPhpEngine->evaluatePath()
#5 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/View/View.php(195): IlluminateViewEnginesCompilerEngine->get()
#6 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/View/View.php(178): IlluminateViewView->getContents()
#7 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/View/View.php(147): IlluminateViewView->renderContents()
#8 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Http/Response.php(69): IlluminateViewView->render()
#9 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Http/Response.php(35): IlluminateHttpResponse->setContent()
#10 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Routing/Router.php(911): IlluminateHttpResponse->__construct()
#11 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Routing/Router.php(878): IlluminateRoutingRouter::toResponse()
#12 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Routing/Router.php(798): IlluminateRoutingRouter->prepareResponse()
#13 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): IlluminateRoutingRouter->IlluminateRouting{closure}()
#14 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#15 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): IlluminateRoutingMiddlewareSubstituteBindings->handle()
#16 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#17 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): IlluminateFoundationHttpMiddlewareVerifyCsrfToken->handle()
#18 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#19 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): IlluminateViewMiddlewareShareErrorsFromSession->handle()
#20 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#21 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): IlluminateSessionMiddlewareStartSession->handleStatefulRequest()
#22 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): IlluminateSessionMiddlewareStartSession->handle()
#23 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#24 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): IlluminateCookieMiddlewareAddQueuedCookiesToResponse->handle()
#25 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#26 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): IlluminateCookieMiddlewareEncryptCookies->handle()
#27 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#28 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Routing/Router.php(798): IlluminatePipelinePipeline->then()
#29 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Routing/Router.php(777): IlluminateRoutingRouter->runRouteWithinStack()
#30 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Routing/Router.php(741): IlluminateRoutingRouter->runRoute()
#31 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Routing/Router.php(730): IlluminateRoutingRouter->dispatchToRoute()
#32 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(200): IlluminateRoutingRouter->dispatch()
#33 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): IlluminateFoundationHttpKernel->IlluminateFoundationHttp{closure}()
#34 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#35 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): IlluminateFoundationHttpMiddlewareTransformsRequest->handle()
#36 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): IlluminateFoundationHttpMiddlewareConvertEmptyStringsToNull->handle()
#37 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#38 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): IlluminateFoundationHttpMiddlewareTransformsRequest->handle()
#39 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): IlluminateFoundationHttpMiddlewareTrimStrings->handle()
#40 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#41 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): IlluminateFoundationHttpMiddlewareValidatePostSize->handle()
#42 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#43 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): IlluminateFoundationHttpMiddlewarePreventRequestsDuringMaintenance->handle()
#44 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php(49): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#45 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): IlluminateHttpMiddlewareHandleCors->handle()
#46 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#47 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): IlluminateHttpMiddlewareTrustProxies->handle()
#48 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#49 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(175): IlluminatePipelinePipeline->then()
#50 /home/photodb/gabriel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(144): IlluminateFoundationHttpKernel->sendRequestThroughRouter()
#51 /home/photodb/gabriel/public/index.php(51): IlluminateFoundationHttpKernel->handle()
#52 {main}
2
Answers
does it work when you add a slash before the class?
new ZipArchive();
The PHP that runs embedded in the web server and the PHP that runs in the CLI use two different configurations, but you’ve got the zip extension enabled only in the CLI version. You’ll need it enabled in the web version as well.
Run
php -m
from the CLI and you’ll see that it includeszip
in the list of loaded modules.But run
phpinfo();
in a script served by the web server (i.e., not from the CLI) and you’ll see that the zip module is not loaded.You can see what INI file(s) it’s loading via the sections titled
Loaded Configuration File
,Scan this dir for additional .ini files
, andAdditional .ini files parsed
. These will list all the ini files read by the web server, make sure that one of them contains the line:This change will require restarting the web server.