遇到一个 Laravel 因配置加载而导致的问题,页面提示:
Whoops, looks like something went wrong.
查看日志 ( tail -f storage/logs/laravel.log
) 显示:
production.ERROR: exception 'RuntimeException' with message 'No supported encrypter found. The cipher and / or key length are invalid.' in ...vendor/laravel/framework/src/Illuminate/Encryption/EncryptionServiceProvider.php:45
提示没有找到支持的 encrypter,或 key 不正确。 认为此问题和 APP_KEY 有关。
APP_KEY 是什么?
也就是这个key是一个随机字符串,用于实现框架中的encrypt(加密)服务,例如存储用户的session,cookie等,从而确保信息安全。可以通过
php artisan key:generate
将该 key 更新.
> losf -i :80
显示:Apache
> loate
位置:/www/wwwroot/
> httpd -V|grep 'SERVER_CONFIG_FILE'
配置文件:conf/httpd.conf
> php --ini
位置: /www/server/php/56/etc/php.ini
搜素了一番,网上不外乎以下几种解决方法:
php artisan key:generate
重新生成 APP_KEY尝试后,均无效果。
给报错的文件 EncryptionServiceProvider.php:45
加断点:
protected function getEncrypterForKeyAndCipher($key, $cipher)
{
dd($key, $cipher); // $key = null
if (Encrypter::supported($key, $cipher)) {
return new Encrypter($key, $cipher);
} elseif (McryptEncrypter::supported($key, $cipher)) {
return new McryptEncrypter($key, $cipher);
} else {
throw new RuntimeException('No supported encrypter found. The cipher and / or key length are invalid.');
}
}
发现 $key 为 null
执行 composer info
查看下依赖,提示:
Warning: putenv() has been disabled for security reasons in...
怀疑 PHP 系统函数 putenv
被禁用,导致 .env 配置无法被框架读取。
php.ini:
; disable_functions = passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
于是,解禁该函数。composer 可以使用了。但是配置文件问题依然存在。
尝试重启 apache:
> apachectl restart
> httpd reload
> killall httpd && httpd
均无作用。
于是乎,接着查看 apache 配置文件:
.
.
.
#PHP
SetHandler "proxy:unix:/tmp/php-cgi-56.sock|fcgi://localhost"
.
.
.
在已有的知识里,apache 应该通过 PHP-module 的方式转发请求。但这里用了 php-fpm。
重启 php-fpm
> killall php-fpm
> php-fpm
刷新页面,问题解决。