From: adrianrb93 at gmail dot com
Operating system: MACOS 10.12.14
PHP version: 7.0.17
Package: Class/Object related
Bug Type: Feature/Change Request
Bug description:Behaviour Change: Non-static method should not be called statically
Description:
------------
I added to my class a non-static method intentionally expecting that if
it is called statically, it will direct to the __callStatic() magic
method.
Use Case:
I am using Laravel. On its model classes:
* Model: calling a non-existing static method is handled by
__callStatic(), for this example lets pretend its ->admin()
* Model: callStatic creates a query builder class and attempts to run
the method on that
* Query Builder: The query builder does not have this method so it is
handled by __call()
* Query Builder: __call() will try to call the method on the Model
prepended with 'scope': `$this->getModel()->scopeAdmin($this,
...$parameters)`
* Model: The scopeAdmin() method exists
In my test script example, I will be using a scopeOpened() and an
opened() method, both which are non-static methods.
Test script:
---------------
<?php
/**
*
----------------------------------------------------------------------------
* Instructions:
*
----------------------------------------------------------------------------
* Install a new Laravel 5.4 app and place this test script in:
app/Shop.php
*
* In the Laravel project run composer install. The `php artisan
tinker`
* command will give you the same test environment to test the
behaviour.
*/
/**
*
----------------------------------------------------------------------------
* Expected Result:
*
----------------------------------------------------------------------------
* $ php artisan tinker
* Psy Shell v0.8.3 (PHP 7.0.17 â cli) by Justin Hileman
* >>> App\Shop::opened('2017-04-13')
* => App\Shop {#970
* owner_id: null,
* day_of_the_week: 4,
* start_date: "2017-04-13",
* end_date: "2017-04-13",
* }
*/
/**
*
----------------------------------------------------------------------------
* Actual Result:
*
----------------------------------------------------------------------------
* $ php artisan tinker
* Psy Shell v0.8.3 (PHP 7.0.17 â cli) by Justin Hileman
* >>> App\Shop::opened('2017-04-13')
* ErrorException with message 'Non-static method App\Shop::opened()
should not be called statically'
*/
namespace App;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model as BaseModel;
class Shop extends BaseModel
{
/**
* This is what is expected to be run when Shop::opened() is
called.
*
* - Shop::opened()
* -> Model::__callStatic()
* -> $builder->opened()
* -> $builder->__call()
* -> $model->scopeOpened()
* -> $model->opened()
*
* The above will not work because within a static context, PHP
attempts
* to call the non-static method opened() instead of directing the
call
* to __callStatic().
*
* @param Illuminate\Database\Eloquent\Builder $query
* @return $this Usually you return the query builder, but my
intent is
* to have data pulled from the query builder,
then
* $model->opened() be called.
*/
public function scopeOpened($query, $date)
{
return $query->getModel()->fill([
//
----------------------------------------------------------------
// This is an example, the query builder could have added
// where owner_id = '1'. This scope method is here to
direct to
// the opened() method on the query builders model instance
with
// the owner_id provided if given in the query.
//
// This is to show I have an actual need for the behaviour
I'm
// requesting.
//
----------------------------------------------------------------
'owner_id' => self::extractWhereValueFromQuery($query,
'owner_id'),
])->opened($date);
}
/**
* This is intended to only be called in a non-static context. The
* behaviour I'm requesting is for PHP to see this isn't a static
method
* and instead direct to the magic __callStatic() method.
*
* @param Carbon\Carbon|string $date
* @return $this
*/
public function opened($date)
{
$date = self::resolveDate($date);
return $this->fill([
'day_of_week' => $date->dayOfWeek,
'start_date' => $date->toDateString(),
'finish_date' => $date->toDateString(),
]);
}
/**
* Extract column value from query builders where clause.
*
* @param Illuminate\Database\Eloquent\Builder $query
* @param string $column
* @return mixed
*/
public static function extractWhereValueFromQuery($query, $column)
{
return collect( $query->getQuery()->wheres )
->filter(function ($where) use ($column) {
return $where['column'] === $column;
})
->pluck('value')
->first();
}
/**
* Resolve a variable to a Carbon instance.
*
* @param mixed $date
* @return Carbon\Carbon
*/
public static function resolveDate($date)
{
if (is_string($date)) {
$date = Carbon::parse($date);
}
if ($date instanceof Carbon === false) {
return Carbon::now();
}
return $date;
}
}
Expected result:
----------------
$ php artisan tinker
Psy Shell v0.8.3 (PHP 7.0.17 â cli) by Justin Hileman
>>> App\Shop::opened('2017-04-13')
=> App\Shop {#970
owner_id: null,
day_of_the_week: 4,
start_date: "2017-04-13",
end_date: "2017-04-13",
}
Actual result:
--------------
$ php artisan tinker
Psy Shell v0.8.3 (PHP 7.0.17 â cli) by Justin Hileman
>>> App\Shop::opened('2017-04-13')
ErrorException with message 'Non-static method App\Shop::opened() should
not be called statically'
--
Edit bug report at https://bugs.php.net/bug.php?id=74425&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=74425&r=trysnapshot54
Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=74425&r=trysnapshot55
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=74425&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=74425&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=74425&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=74425&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=74425&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=74425&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=74425&r=support
Expected behavior: https://bugs.php.net/fix.php?id=74425&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=74425&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=74425&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=74425&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=74425&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=74425&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=74425&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=74425&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=74425&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=74425&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=74425&r=mysqlcfg