laravel count():参数必须是一个数组或者一个实现了Countable的对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48343557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
count(): Parameter must be an array or an object that implements Countable
提问by Khaled Al-Shehri
I'm facing strange case. I face an error in production env not while in dev it's working fine.
我面临着奇怪的情况。我在生产环境中遇到错误,而不是在开发环境中它工作正常。
Development: Laravel 5.4.28 PHP 7.0.13 MYSQL 5.7.17
开发:Laravel 5.4.28 PHP 7.0.13 MYSQL 5.7.17
Production: Laravel 5.4.28 PHP 7.2.1 MYSQL 5.7.20
生产:Laravel 5.4.28 PHP 7.2.1 MYSQL 5.7.20
In implementation code. I used:
在实现代码中。我用了:
namespace App;
use Illuminate\Support\Facades\Storage;
use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;
class Artwork extends Model
{
use Searchable;
In development it works fine. But in production it gives me this error: count(): Parameter must be an array or an object that implements Countable in Builder.php (line 936)
在开发中它工作正常。但是在生产中它给了我这个错误:count(): Parameter must be an array or an object that implementation Countable in Builder.php (line 936)
as you can see in this pic:
正如你在这张照片中看到的:
Any idea what is the reason behind this? and how to fix?
知道这背后的原因是什么吗?以及如何解决?
回答by Akash Kulshrestha
/Put this code at the beginning your routes file its will work fine/
/将此代码放在路由文件的开头,它会正常工作/
if(version_compare(PHP_VERSION, '7.2.0', '>=')) {
error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING);
}
回答by Ben Harold
This is a documented change in PHP 7.2. You need to either update Laravel to 5.6 or downgrade PHP to version 7.1.
这是PHP 7.2 中记录的更改。您需要将 Laravel 更新到 5.6 或将 PHP 降级到 7.1 版。
回答by Akif Hussain Sayyed
Replace
代替
$originalWhereCount = count($query->wheres);
by
经过
$originalWhereCount = count((array)$query->wheres);
in
在
\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Builder.php
\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Builder.php
回答by Farid Abbas
I was facing similar issue in Laravel 5.6. Where I was getting error for object based array. I knew that data in that particular variable will always remain object so i used to convert the object to array. Here is code sample:
$objectData = (array)$objectData;
echo "Total Elements in array are: ".count($objectData);
我在 Laravel 5.6 中遇到了类似的问题。我在基于对象的数组中遇到错误的地方。我知道该特定变量中的数据将始终保留为对象,因此我曾经将对象转换为数组。这是代码示例:
$objectData = (array)$objectData;
echo "Total Elements in array are: ".count($objectData);
回答by paulie3001
In php 7.2+ count does not work on relation objects, you need to use:
在 php 7.2+ 中 count 不适用于关系对象,您需要使用:
$model->relation()->exists()
$model->relation()->exists()
Not this (less than php 7.2):
不是这个(小于 php 7.2):
count($model->relation)
计数($模型->关系)
回答by Jelena Grujin
Model looking for countable parameter:
寻找可数参数的模型:
class ClassName extend Model {
protected $fillable=['column_name']; // column in DB of Model is in array
}
回答by cautionbug
i ran into the same problem (PHP 7.2 + Laravel 5.3) but i don't see any "good" answers here. For me, the problem occurs when i tried to start a Builder from a scope method on the model: SomeModel::forUser() calls scopeForUser()
. Trying to build a new Query, it trips on a count($this->wheres)
that gets no initial value (null
). Because the magic static call to the scope starts the builder, no other conditions have been placed in the object so the property is still null
at that point.
我遇到了同样的问题(PHP 7.2 + Laravel 5.3),但我在这里没有看到任何“好的”答案。对我来说,当我试图从模型上的范围方法开始生成器出现问题:SomeModel::forUser() calls scopeForUser()
。尝试构建一个新的 Query,它在count($this->wheres)
没有初始值 ( null
)上跳闸。因为对作用域的神奇静态调用启动了构建器,所以没有在对象中放置其他条件,所以属性仍然null
在那个点。
i thought it's worth sharing my solution first, then perspective on why i consider it better than Ben's answer. It's not personal, i just disagree.
我认为值得先分享我的解决方案,然后再谈谈为什么我认为它比 Ben 的答案更好。这不是个人的,我只是不同意。
Solution
解决方案
i took a cue from this answerabout overriding some of the core Illuminate\Database
classes...
我从这个答案中得到了一个关于覆盖一些核心Illuminate\Database
类的提示......
- Extend
Illuminate\Database\Eloquent\Model
Mine isApp\Overrides\Database\Eloquent\Model
- Extend
Illuminate\Database\Eloquent\Builder
Mine isApp\Overrides\Database\Eloquent\Builder
- Extend
Illuminate\Database\Query\Builder
Can you guess?App\Overrides\Database\Query\Builder
- Tell Laravel to use YOUR
Eloquent\Model
:
config/app.php'aliases'
array, replace the'Eloquent'
value
with yourEloquent\Model
FQN
- 扩展
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
- 告诉 Laravel 使用 YOUR
Eloquent\Model
:
config/app.php'aliases'
数组,将'Eloquent'
值替换为
您的Eloquent\Model
FQN
My Model
:
我的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());
}
}
My Eloquent\Builder
:
我的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.
}
}
My Query\Builder
:
我的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.
}
}
This safely preserves the framework's functionality, since the only actual change you're making is initializing properties that should have been in the first place. Everything else will pass instanceof
checks used for dynamic loading and dependency injection.
这安全地保留了框架的功能,因为您所做的唯一实际更改是初始化本应首先设置的属性。其他一切都将通过instanceof
用于动态加载和依赖注入的检查。
Opinion
观点
While i agree with @ben-harold about every comment he made saying "NEVER edit vendor code," i disagree with the "solution." It's an oversimplification to a much more complex problem.
虽然我同意 @ben-harold 关于他所说的“永远不要编辑供应商代码”的每一条评论,但我不同意“解决方案”。这是对一个更复杂的问题的过度简化。
Upgrade Laravel: to ensure support for PHP 7.2, jumping up several minor versions - if not major releases - is impractical for a lot of teams. As a long term objective, yes of course. As something i can do to get rid of the bug for my deadline? Nope. Upgrading takes a lot of planning and frequently a lot of rewrites as structures, names, and functionality change. It's something to prioritize, but not a need-it-now answer.
升级 Laravel:为了确保对 PHP 7.2 的支持,跳上几个小版本 - 如果不是主要版本 - 对于很多团队来说是不切实际的。作为长期目标,当然可以。作为我可以做些什么来摆脱我最后期限的错误?不。随着结构、名称和功能的变化,升级需要大量的计划和频繁的重写。这是需要优先考虑的事情,但不是现在需要的答案。
Downgrade PHP: same problem. Downgrading into PHP 5.x means A) PHP is EOL, which may be a deal breaker for a lot of customers who have security policies, and B) any usage of PHP 7.x language features have to be scrapped. As with upgrading the framework this is very likely to cause a lot of headaches. It's also an even less useful solution, since walking backward in the language just puts you farther behind and will require more long-term effort.
降级 PHP:同样的问题。降级到 PHP 5.x 意味着 A) PHP 已停产,这对于许多拥有安全策略的客户来说可能是一个交易破坏者,并且 B) 必须废弃任何对 PHP 7.x 语言功能的使用。与升级框架一样,这很可能会引起很多麻烦。这也是一个更没用的解决方案,因为在语言中倒退只会让你落后更远,需要更多的长期努力。
回答by ILIAS M. DOLAPO
place the below line ob code before the class name in your controllers
将以下行 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
}
回答by Yogesh More
I was facing the same issue with an external created table (Not using migration or command),
After creating the model, I just assigned a table name, but the problem was in my model protected $fillable
where I assign string instead of array and error occurred.
There is 2 possible solution for that.
我在使用外部创建的表(不使用迁移或命令)时遇到了同样的问题,创建模型后,我只分配了一个表名,但问题出在我的模型中protected $fillable
,我分配了字符串而不是数组,并且发生了错误。有 2 种可能的解决方案。
- Assign an array to your
protected $fillable = ['filed1', 'filed2'];
- Remove
protected $fillable
completely (Not Recommended)
- 为您分配一个数组
protected $fillable = ['filed1', 'filed2'];
protected $fillable
完全删除(不推荐)
class Abc extends Model
{
protected $table = 'cities';
protected $fillable = ['field1','field2', ...];
}
回答by Debraj Ghosh
'vendor\laravel\framework\src\Illuminate\Database\Eloquent\Builder.php' to:
'vendor\laravel\framework\src\Illuminate\Database\Eloquent\Builder.php' 到:
$originalWhereCount = is_array($query->wheres) ? count($query->wheres) : 0;