我面临着奇怪的情况。我在生产环境中遇到错误,而在开发环境中工作正常。
发展: Laravel 5.4.28 PHP 7.0.13 MYSQL 5.7.17
生产: Laravel 5.4.28 PHP 7.2.1 MYSQL 5.7.20
在实施代码中。我用过:
namespace App;
use Illuminate\Support\Facades\Storage;
use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;
class Artwork extends Model
{
use Searchable;
在开发中它运作良好。但在生产中它给了我这个错误: count():参数必须是实现Countable的数组或对象 在Builder.php中(第936行)
你可以在这张照片中看到: enter image description here 不知道这背后的原因是什么?以及如何解决?
答案 0 :(得分:15)
这是documented change in PHP 7.2。您需要将Laravel更新为5.6或将PHP降级到7.1版。
答案 1 :(得分:11)
/ 将此代码放在路由文件的开头,即可正常运行 /
if(version_compare(PHP_VERSION, '7.2.0', '>=')) {
error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING);
}
答案 2 :(得分:5)
在php 7.2+中,计数不适用于关系对象,您需要使用:
$ model-> relation()-> exists()
不是这样(低于php 7.2):
count($ model-> relation)
答案 3 :(得分:2)
替换
$originalWhereCount = count($query->wheres);
通过
$originalWhereCount = count((array)$query->wheres);
在
\ vendor \ laravel \ framework \ src \ Illuminate \ Database \ Eloquent \ Builder.php
答案 4 :(得分:2)
当我更新到 PHP 7.2 时,我的服务器使用的是 PHP 7.1 。
搜索后,我发现了为什么会这样。 (这是由于PHP更新引起的。)
因此,在我的情况下,错误是通过类型转换解决的。
我只是更新我以前计算过的所有代码
之前
y
更新后
import numpy as np
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
stages = [102, 103, 104, 106]
reject_count = [1, 3, 1, 2]
li = []
li.append(stages)
l2 = []
l2.append(reject_count)
x = np.array(li)
y = np.array(reject_count)
x.shape
y.shape
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)
print("===============")
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
regressor = RandomForestRegressor(n_estimators=100, random_state=0)
print("x train", X_train)
print("y train", y_train)
regressor.fit(X_train, y_train)
y_pred = regressor.predict(X_test)
print(y_pred)
好运
答案 5 :(得分:1)
寻找可数参数的模型:
class ClassName extend Model {
protected $fillable=['column_name']; // column in DB of Model is in array
}
答案 6 :(得分:1)
我遇到了同样的问题(PHP 7.2 + Laravel 5.3),但是我在这里看不到任何“好的”答案。对我来说,当我尝试从模型SomeModel::forUser() calls scopeForUser()
上的作用域方法启动Builder时,就会出现问题。尝试构建新查询时,它在没有初始值(count($this->wheres)
)的null
上跳闸。因为对作用域的魔术静态调用启动了构建器,所以没有在对象中放置其他条件,因此该属性此时仍为null
。
我认为有必要先分享我的解决方案,然后再思考为什么我认为它比Ben的回答更好。这不是私人的,我只是不同意。
我从this answer那里得到了一个提示,它要重写某些核心Illuminate\Database
类...
Illuminate\Database\Eloquent\Model
App\Overrides\Database\Eloquent\Model
Illuminate\Database\Eloquent\Builder
App\Overrides\Database\Eloquent\Builder
Illuminate\Database\Query\Builder
App\Overrides\Database\Query\Builder
Eloquent\Model
:'aliases'
数组,替换'Eloquent'
值Eloquent\Model
FQN 我的Model
:
namespace App\Overrides\Database\Eloquent;
/*
* Notes:
* * Using replacement Query\Builder with ALIAS
* * Use of Builder in this class is MY Eloquent\Builder
*/
use App\Overrides\Database\Query\Builder as QueryBuilder;
use Illuminate\Database\Eloquent\Model as EloquentModel;
class Model extends EloquentModel
{
public function newEloquentBuilder($query)
{
return new Builder($query);
}
protected function newBaseQueryBuilder()
{
$conn = $this->getConnection();
$grammar = $conn->getQueryGrammar();
return new QueryBuilder($conn, $grammar, $conn->getPostProcessor());
}
}
我的Eloquent\Builder
:
namespace App\Overrides\Database\Eloquent;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
class Builder extends EloquentBuilder
{
public function __construct($query)
{
parent::__construct($query);
/*
* FIX #1: Set properties treated AS arrays
* to empty arrays on construct.
*/
$this->wheres = [];
// Any other properties treated as arrays should also be initialized.
}
}
我的Query\Builder
:
namespace App\Overrides\Database\Query;
use Illuminate\Database\Query\Builder as QueryBuilder;
class Builder extends QueryBuilder
{
public function __construct()
{
parent::__construct(...func_get_args());
/*
* FIX #2: Set properties treated AS arrays
* to empty arrays on construct.
*/
$this->wheres = [];
// Any other properties treated as arrays should also be initialized.
}
}
这安全地保留了框架的功能,因为您所做的唯一实际更改是初始化应该放在首位的属性。其他所有内容都将通过用于动态加载和依赖项注入的instanceof
检查。
虽然我同意@ ben-harold的评论,但他不同意“解决方案”。对于一个更为复杂的问题,这过于简单了。
升级Laravel:为确保对PHP 7.2的支持,跳多个次要版本(如果不是主要版本)对于许多团队来说是不切实际的。从长远来看,当然可以。作为我可以做的一些事情,可以在最后期限内摆脱错误?不。升级需要大量计划,并且随着结构,名称和功能的更改,经常需要进行大量重写。这是要确定优先级的事情,但不是现在需要的答案。
PHP降级:同样的问题。降级到PHP 5.x意味着A)PHP是EOL,对于拥有安全策略的许多客户而言,这可能是一个破坏交易的事物,并且B)必须放弃使用PHP 7.x语言功能的任何使用。与升级框架一样,这很可能引起很多麻烦。这也是一种不太有用的解决方案,因为使用该语言向后走会使您走得更远,并且需要更多的长期努力。
答案 7 :(得分:0)
将下面的行ob代码放在控制器中的类名之前
if (version_compare(PHP_VERSION, '7.2.0', '>=')) {
// Ignores notices and reports all other kinds... and warnings
error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING);
// error_reporting(E_ALL ^ E_WARNING); // Maybe this is enough
}
答案 8 :(得分:0)
在您的web.php文件中添加以下代码
if (version_compare(PHP_VERSION, '7.2.0', '>=')) {
error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING);
}
答案 9 :(得分:0)
我在使用外部创建的表时遇到了同样的问题(不使用迁移或命令),
创建模型后,我只是分配了一个表名,但是问题出在我的模型protected $fillable
中,我在其中分配了字符串而不是数组,并且发生了错误。
有两种可能的解决方案。
protected $fillable = ['filed1', 'filed2'];
protected $fillable
(不推荐)class Abc extends Model
{
protected $table = 'cities';
protected $fillable = ['field1','field2', ...];
}
答案 10 :(得分:0)
'vendor \ laravel \ framework \ src \ Illuminate \ Database \ Eloquent \ Builder.php'到:
$originalWhereCount = is_array($query->wheres) ? count($query->wheres) : 0;
答案 11 :(得分:0)
I; m使用laravel 6.x 在这种情况下,您可以使用以下方式:
$id = \DB::table('xxxx')->where('id', $id)->count();
答案 12 :(得分:-2)
我在Laravel 5.6中解决了这个问题
//在控制器中
public function index()
{
$todos = Todo::all();
return view('todos.index')->with(['todos' => $todos]);
}
//在视图页面
@if(count($todos) > 0)
@foreach($todos as $todo)
<div class="well">
<h3>{{$todo->text}}</h3>
<span class="label label-danger">{{$todo->due}}</span>
</div>
@endforeach
@endif