I try to look at all the files in nesbot/carbon vendor source code but still can't find the implementation of some methods likes roundCentury, addDay, addDays... except the php docblock.
Because I want to know how these methods work. I wonder where is implementation of these method?
Thanks in advance
CodePudding user response:
round***
supports dynamically any unit, so there is no had-coded method for each of them but one single method and __call()
takes care to parse the method name and select the appropriate unit:
https://github.com/briannesbitt/Carbon/blob/b017c794d31626a324c8216ff222fb895306c911/src/Carbon/Traits/Rounding.php#L40
CodePudding user response:
The code structure of Carbon is rather complicated, including heavy use of PHP traits and a custom "macro" system, but eventually I tracked down the definition to Carbon\Traits\Date
which is included into the main classes like Carbon\Carbon
.
This doesn't define the methods directly, but rather implements method overloading via __call
, where the method name is passed in as a string. The Carbon code actually parses the method name to decide what it should do.
For rounding, that calls roundMethod
, which is defined in another trait, called Carbon\Traits\IntervalRounding
, the main line of which is this:
return $this->{$action.'Unit'}(substr($method, \strlen($action)), ...$parameters);
For roundCentury
, $action
is "round", and the substr
part takes the rest of the name, so you get:
return $this->roundUnit('Century', ...$parameters);
The definition of roundUnit
is then in yet another trait, Carbon\Traits\Rounding
.
The "add..." methods presumably work similarly.
CodePudding user response:
A function with the name addDay is not listed in the sources of Carbon. It is therefore difficult to find the place where the actual action takes place. When addDay is called, the magic function __call() in Traits/Date.php becomes active. There it is split into an "add" action and a "Day" unit and branched to addUnit() method. There we will find the actual action:
$date = $date->modify("$value $unit");