How do I disable Laravel view cache? - caching

I have an exception in one of my views. However, instead of telling me the name of the view so I can find it and fix it, laravel says it is in app/storage/views/110a3ecc0aa5ab7e6f7f50ef35a67a8b, which is meaningless.
How do I disable this view caching, so that laravel uses and refers to the actual files?

Out of the box? You can't. But you can extend the BladeCompiler class, overriding the method resposible for checking if the view has been expired:
class MyBladeCompiler extends BladeCompiler {
public function isExpired($path)
{
if ( ! \Config::get('view.cache'))
{
return true;
}
return parent::isExpired($path);
}
}
You'll need to replace the BladeCompiler instance in IoC container, with your own compiler:
$app = App::make('app'); // or just $app = app();
$app->bindShared('blade.compiler', function($app)
{
$cache = $app['path.storage'].'/views';
return new MyBladeCompiler($app['files'], $cache);
});
And then you just need to create that key in your app/config/view.php file
<?php
return [
'cache' => false,
'paths' => [base_path().'/resources/views'],
'pagination' => 'pagination::slider-3',
];
Or, like I do here:
return [
'cache' => in_array(App::environment(), ['production', 'staging']),
];

this worked for me... added this to the .env file
CACHE_EXPIRE=-1

In latest version of laravel (> v9.7.0), you can now add inside config/view.php:
'cache' => App::environment('local') ? false : true
Here is the PR: https://github.com/laravel/framework/pull/41859

Solution
open php.ini
opcache.revalidate_freq=0
opcache.fast_shutdown=0
change to this. restart apache.

check your .env file
Change CACHE_DRIVER=file to CACHE_DRIVER=array

If you have artisan, it's easy to clear the cache
php artisan view:clear
If you don't have or don't want artisan (can't think why you wouldn't want it, it's very useful), you can from the root of your project do
cd storage/framework/views/
rm *.php

Laravel Creates view cache file because it has been told to do that. In .env File you will come across cache_driver which has default property as file change it to array.

You can clear cache in this way, as well:
// Clear cache in laravel
Route::get('/clear-cache', function() {
Artisan::call('cache:clear');
// return what you want
return "Cache is cleared";
});

Here is the full answer
Go to vendor/illuminate/BladeCompiler.php
change these 2 lines
use Illuminate\View\Compilers\Compiler;
class BladeCompiler extends Compiler implements CompilerInterface
with the following:
use App\Support\CustomCompiler;
class BladeCompiler extends CustomCompiler implements CompilerInterface
in your app/support folder (or whatever structure you are using)
create the following class
namespace App\Support;
use Illuminate\View\Compilers\Compiler;
class CustomCompiler extends Compiler {
public function isExpired($path) {
if ( !\config('blade.use_cache'))
return true;
return parent::isExpired($path);
}
}
your blade config file will look like this
return [
'use_cache' => false,
'cache' => storage_path('cache'),
'views' => resources_path('views')
];
auto dump and run....

If you are using MAMP, disable OPCache under Preferences, General, PHP-Cahce. just select off. thank me later.

Although some would call this sketchy, this was the quickest and most minimal way to do this on a small application I was working on
On the controller(s) that my routes pointed to:
public function __construct()
{
exec('php /full/path/to/artisan view:clear');
}

A bit late to the party, however.
I had the same issue: the browser not reflecting changes to the php code.
Simple solution for me was:
set the clock on the server to the same time as the dev computer !
sudo date +%T -s "11:14:00"

In development environment, I just add and modify the next:
bootstrap/start.php
$env = $app->detectEnvironment(function(){return 'testing';});
app/config/testing/cache.php add in array
'cache' => false,
app/config/view.php add in array
'cache' => false,

Related

Laravel - timezone - Config null

I installed laravel-timezone as described here: https://github.com/jamesmills/laravel-timezone
also added teh configuration file, and in the configuraiton file there is this:
timezone.php
'lookup' => [
'server' => [
'REMOTE_ADDR',
],
'headers' => [
],
],
After the login, the script is suposed to update the timezone automatically, but I get Invalid argument supplied for foreach() in the file \vendor\jamesmills\laravel-timezone\src\Listeners\Auth\UpdateUsersTimezone.php:111
the function is this:
/**
* #return mixed
*/
private function getFromLookup()
{
$result = null;
foreach (config('timezone.lookup') as $type => $keys) {
if (empty($keys)) {
continue;
}
$result = $this->lookup($type, $keys);
if (is_null($result)) {
continue;
}
}
return $result;
}
I tried to put a dd() there, and config('timezone.lookup') is null..
why does it return null, if the file exists, and a value is assigned in the file?
Is there anything I have to do to make this timezone.php accesisble?
When you are caching the configuration Laravel creates a file in bootstrap/cache/config.php with all the configuration. After this is done the individual cache files and the .env file are no longer read.
You therefore need to clear your config cache, and I recommend to not cache it while in development. Only cache the config in production.
Just run:
php artisan cache:clear
Sorry you’re having issues using the package. As far as I’m aware you don’t have to publish the config for the package to work after initial install. It should pick up defaults so you should be able to install it and go! However, like others have said, if you do publish the config then please try to flush your config cache php artisan cache:clear
Thank you #apokryfos for your help on this issue.
If you have any further issues please don’t hesitate to reply.
James

Laravel Route Controller issue

I am trying to add a new route to my application and can't seem to get it to work. I keep getting a 404 error. It looks like the physical path is looking at the wrong directory. Currently looking at D:\Web\FormMapper\blog\public\forms but should be looking at D:\Web\FormMapper\blog\resources\view\layout\pages\forms.blade.php
My request URL:
http://localhost/FormMapper/ /works fine
http://localhost/FormMapper/forms /doesn't work
http://localhost/FormMapper/forms.php /No input file specified.
my FormsController:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class FormsController extends Controller
{
public function index()
{
return view('layouts.pages.forms');
}
}
My web.php:
Route::get('/', function () {
return view('layouts/pages/login');
});
Route::get('/forms', 'FormsController#index');
My folder structure looks like this:
My config/view.php
return [
'paths' => [
resource_path('views'),
],
'compiled' => env(
'VIEW_COMPILED_PATH',
realpath(storage_path('framework/views'))
),
];
you must use dot for this. In your controller change to this:
return view('layouts.pages.forms');
If your route only needs to return a view, you may use the Route::view method. Like the redirect method, this method provides a simple shortcut so that you do not have to define a full route or controller. The view method accepts a URI as its first argument and a view name as its second argument. In addition, you may provide an array of data to pass to the view as an optional third argument:
Route::view('/', 'layouts.pages.login');
Route::view('/forms', 'layouts.pages.forms', ['foo' => 'bar']);
Check docs
After tracking digging deeper I determined that the issue was that IIS requires URL rewrite rules in place for Laravel to work properly. The index.php and '/' route would work b/c it was the default page but any other pages wouldn't. To test this I used the
php artisan serve
approach to it. and everything worked properly. Unfortunately I am unable to do this in production so I needed to get it to work with IIS.

testing in Laravel 5.5 : Class env does not exist

i am starting tests in laravel
i created a ".env.testing" file with this
APP_NAME=myApp
APP_ENV=testing
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://myApp.localhost
DB_CONNECTION=sqlite_testing
i added this in the "connections" part of config/database.php file
...
'sqlite_testing' => [
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => '',
],
...
in the phpunit.xml file, i added :
<env name="DB_CONNECTION" value="sqlite_testing" />
and i created a UserTest feature :
class UserTest extends TestCase
{
public function setUp()
{
parent::setUp();
Artisan::call('migrate');
Artisan::call('db:seed');
}
public function tearDown()
{
parent::tearDown();
Artisan::call('migrate:reset');
}
public function testCanAccessUserSpace()
{
$user = factory(User::class)->create();
$response = $this->actingAs($user)
->get('/home');
$response->assertStatus(200);
}
}
But when i run the tests, i have this :
ReflectionException: Class env does not exist
What's wrong with my config ?
thanks
I had same error while running the phpunit:
ReflectionException: Class env does not exist
Here was another problem, I've installed package telescope and phpunit tried to load it while testing:
ReflectionException: Class env does not exist
/var/www/html/mat2/vendor/laravel/telescope/src/Telescope.php:263
/var/www/html/mat2/vendor/laravel/telescope/src/Telescope.php:222
and so on.
I've added to phpunit.xml:
<env name="TELESCOPE_ENABLED" value="false"/>
Afterwards, tests are running fine.
So, it may be package testing related error.
If you are using php artisan test --env=testing, add TELESCOPE_ENABLED=false to your .env.testing file and run php artisan config:cache --env=testing.
In my case, set TELESCOPE_ENABLED to false doesn't solve my problem. I have to issue
php artisan config:clear
I use Laravel 7.
Looks like this exception is thrown for a variety of reasons. In your case the issue is with the tearDown function, in specific order of operations within this function. You should call the parent tearDown at the bottom. So this:
public function tearDown()
{
parent::tearDown();
Artisan::call('migrate:reset');
}
Should be refactored as follows:
public function tearDown()
{
Artisan::call('migrate:reset');
parent::tearDown();
}
I suspect the reason is that the app instance gets destroyed inside Illuminate\Foundation\Testing\TestCase. here is the code from Laravel 5.5:
if ($this->app) {
foreach ($this->beforeApplicationDestroyedCallbacks as $callback) {
call_user_func($callback);
}
$this->app->flush();
$this->app = null;
}
This error can be caused by telescope being turned on in a unit testing environment.
I change the default behaviour of telescope to be off and explicitly turn it on in my .env file.
You can change the default to false for telescope by updating your config/telescope.php file.
/*
|--------------------------------------------------------------------------
| Telescope Master Switch
|--------------------------------------------------------------------------
|
| This option may be used to disable all Telescope watchers regardless
| of their individual configuration, which simply provides a single
| and convenient way to enable or disable Telescope data storage.
|
*/
'enabled' => env('TELESCOPE_ENABLED', false), // Change from true to false here.
You will then have to set: TELESCOPE_ENABLED=true in your .env file. This will ensure that you don't have it accidentally turned on in environments you don't want such as production and unit testing.
Might be a bit late for a reply, but the below line in phpunit.xml solved the issue.
<server name="TELESCOPE_ENABLED" value="false"/>
I faced this issue and found issue in config folder > constants file
I was wrote "asset('/')" function in config file, we can't write such functions in config.
Hope this answer will help someone who stuck like this errors.
You need to rename .env.testing to .env, you already set APP_ENV to testing so there is no need to change your .env to .env.testing
EDIT:
Also try to update your dependencies with composer update and try again, it's not a usual bug, so it's something related to your setup of testing environment
I have the same problem in my config/services.php file, my error was calling the route() method in array. I just removed the method and back to works.
For laravel version 8 change app()->environment() to env('ENV_NAME') like
env('SMS_SERVICE_ENDPOINT')
Example:
Previous: app()->environment() === 'production'
New Format should be env('DEV_ENV') === 'production')
Note: Don't forget to add DEV_ENV=production in your .env file
In laravel 8, don't try to use laravel global helper function or Facade after TestCase::tearDown:
class MyTestCase extends TestCase
{
public function tearDown(): void
{
parent::tearDown();
// This will case this exception: Target class [env] does not exist
echo app()->environment();
}
}
Instead, move method BEFORE parent::tearDown, it will work:
public function tearDown(): void
{
echo app()->environment();
parent::tearDown();
}
For posterity, my problem was something else entirely... I was trying to use config or env values in my unit test's "tearDown" method after calling the parent's implementation, which destroyed the application!
So this obviously does not work:
protected function tearDown(): void {
parent::tearDown();
$environment = App::environment();
...
}
but this will...
protected function tearDown(): void {
$environment = App::environment();
...
parent::tearDown();
}

JWTGenerateCommand::handle() does not exist

I am using Laravel 5.4 and JWT Auth Library for user authentication in API development. After installation while i am running php artisan jwt:generate then it throws me error of
Method Tymon\JWTAuth\Commands\JWTGenerateCommand::handle() does not exist
Any idea what i am missing ?
This error generally display when you install jwt package in laravel 5.5 version. then after you set service providers and run following command.
php artisan jwt:generate
then you seen this error message in terminal.
how to resolve it? simple follow this step
Step - 1 Re-install package
composer require tymon/jwt-auth:dev-develop --prefer-source
or the following is a new release package use laravel 6.X
composer require tymon/jwt-auth:1.0.*
in this developement version this errors fixed.
Step - 2 Set Service Provider
'providers' => [
....
Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class to
Tymon\JWTAuth\Providers\LaravelServiceProvider::class
],
Step - 3 Generate key
php artisan jwt:secret
i found this solution from here https://laravelcode.com/post/method-tymonjwtauthcommandsjwtgeneratecommandhandle-does-not-exist
Go to JWTGenerateCommand.php file located in vendor/tymon/src/Commands and paste this method
public function handle() { $this->fire(); }
It's never a great idea to change anything in the vendor folder but the there's two ways to deal with this ...
Generate a random string yourself and just change the value in the JWT config file.
Go to Tymon\JWTAuth\Commands\JWTGenerateCommand and change the fire method to handle.
go to given file path
vendor/tymon/jwt-auth/src/Commands/JWTGenerateCommand.php
change function name
public function fire() to public function handle()
run command:
php artisan jwt:generate
I'm publishing this answer because I have crash in this error more than one time.
The only solution I found that it works with Laravel 5.6 is the following:
Add "tymon/jwt-auth": "1.0.0-rc.1" to composer.json and run composer update
Open config/app.php and add the following:
config/app.php:
'providers' => [
/*
* JWT Service Provider...
*/
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
],
'aliases' => [
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
],
Execute:
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
Finally, execute: php artisan jwt:secret
After all that, when I hit my endpoint for login I got the following exception:
Class Tymon\JWTAuth\Providers\JWT\NamshiAdapter does not exist
This was fixed by:
Open config/jwt.php and change the following:
config/jwt.php:
'jwt' => Tymon\JWTAuth\Providers\JWT\Namshi::class,
'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,
'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,
Finally, note that in order to work your User model should be defined as follows:
class User extends Authenticatable implements JWTSubject
{
...
public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
return [];
}
...
}
I can advise one solution. Go to JWTGenerateCommand.php file located in vendor/tymon/src/Commands and paste this part of code public function handle() { $this->fire(); }
I know this is not an elegant solution, but it works. I hope this might help until official fix arrive.
see here for more info
Change fire() function to handle() in this path
vendor/tymon/jwt-auth/src/commands/JWTGenerateCommand.php
In the file path: /vendor/tymon/jwt-auth/src/Commands/JWTGenerateCommand.php
Add public function
public function handle()
{
$this->fire();
}

One associative array used across all controllers, one place to define it? - Laravel 5.3

I have an associative array which I use in approx all controllers and i was wondering if possible to define that array somewhere at one place and just use in in all controllers?
Kind of like we do in angular.
Like if i can define it in env file or something.
Please let me know if there is a way.
Creating an entry in the config/app.php
'myVar' => [
'key' => 'value'
],
and accesing it via config('app.myVar')
Put it in a helper file and access using that helper file
check out this answer https://stackoverflow.com/a/32772686/5808894
Using AppServiceProvider
In your app/providers/AppServiceProvider.php in the boot method add this, make sure to import App use App in AppServiceProvider
public function boot()
{
App::singleton('myVar', function(){
return [
'key' => 'value'
];
});
}
and access the variable in your controller using app('myVar');
Reference https://stackoverflow.com/a/25190686/5808894
Mentioning it here since no one else did:
public class SharedArrayContainer {
public static $data = [ 'key' => 'value' ];
}
and you can use it as:
SharedArrayContainer::$data
Not as good as adding it to the service container but this is what pre-framework me used to do.
I would recommend to create a provider class (service) for it and use laravel Service Container for injection. This way you can create helper methods like get, find, etc... and make use of laravels Dependency Injection (having single instance injected whenever & almost everywhere you want)
Laravel docs
class ExampelService
{
// associative array
private arr = []
public function get(item) { }
public function save(item) { }
public function has(item) { }
}

Resources