programmatically identify methods that override trait methods
I'm trying to generate an array of methods in a class that override trait methods. Here is a simplified example that shows the structure of methods of a typical class and trait in my app:
class demo
{
public function MethodA()
{
return 'method A from class';
}
public function MethodC()
{
return 'method C from class';
}
public function MethodE()
{
return 'method E from class';
}
use tGeneric;
}
trait tGeneric
{
public function MethodA()
{
return 'method A from trait';
}
public function MethodB()
{
return 'method B from trait';
}
public function MethodD()
{
return 'method D from trait';
}
public function MethodE()
{
return 'method E from trait';
}
}
Per the precedence rules listed in the PHP manual:
The precedence order is that methods from the current class override Trait methods, which in turn override methods from the base class.
this is behaving as expected because the output from this code:
$object = new demo();
$array = [
$object->MethodA(),
$object->MethodB(),
$object->MethodC(),
$object->MethodD(),
$object->MethodE()
];
$br = '<br>';
$msg = '';
foreach ($array as $value):
$msg .= $value . $br;
endforeach;
echo $msg . $br;
is:
The methods in the class demo
that override the trait methods from tGeneric
are MethodA() and MethodE(). Is there a way to programmatically generate an array of just these methods in the class that override the methods from the trait?
I have experimented with reflection but the GetMethods()
method retrieves all methods for a class, regardless of whether they originated in the class or were obtained via the use of a trait.
This code:
$rc = new ReflectionClass('demo');
$d = $rc->GetMethods();
$traits = class_uses('demo');
foreach ($traits as $trait):
$reflection = new ReflectionClass($trait);
$t = $reflection->GetMethods();
endforeach;
DisplayInfo($d);
DisplayInfo($t);
function DisplayInfo($array)
{
$br = '<br>';
echo '<b>' . $array[0]->class . '</b>' . $br;
foreach ($array as $value):
echo $value->name . $br;
endforeach;
echo $br;
}
gives this output:
php
add a comment |
I'm trying to generate an array of methods in a class that override trait methods. Here is a simplified example that shows the structure of methods of a typical class and trait in my app:
class demo
{
public function MethodA()
{
return 'method A from class';
}
public function MethodC()
{
return 'method C from class';
}
public function MethodE()
{
return 'method E from class';
}
use tGeneric;
}
trait tGeneric
{
public function MethodA()
{
return 'method A from trait';
}
public function MethodB()
{
return 'method B from trait';
}
public function MethodD()
{
return 'method D from trait';
}
public function MethodE()
{
return 'method E from trait';
}
}
Per the precedence rules listed in the PHP manual:
The precedence order is that methods from the current class override Trait methods, which in turn override methods from the base class.
this is behaving as expected because the output from this code:
$object = new demo();
$array = [
$object->MethodA(),
$object->MethodB(),
$object->MethodC(),
$object->MethodD(),
$object->MethodE()
];
$br = '<br>';
$msg = '';
foreach ($array as $value):
$msg .= $value . $br;
endforeach;
echo $msg . $br;
is:
The methods in the class demo
that override the trait methods from tGeneric
are MethodA() and MethodE(). Is there a way to programmatically generate an array of just these methods in the class that override the methods from the trait?
I have experimented with reflection but the GetMethods()
method retrieves all methods for a class, regardless of whether they originated in the class or were obtained via the use of a trait.
This code:
$rc = new ReflectionClass('demo');
$d = $rc->GetMethods();
$traits = class_uses('demo');
foreach ($traits as $trait):
$reflection = new ReflectionClass($trait);
$t = $reflection->GetMethods();
endforeach;
DisplayInfo($d);
DisplayInfo($t);
function DisplayInfo($array)
{
$br = '<br>';
echo '<b>' . $array[0]->class . '</b>' . $br;
foreach ($array as $value):
echo $value->name . $br;
endforeach;
echo $br;
}
gives this output:
php
add a comment |
I'm trying to generate an array of methods in a class that override trait methods. Here is a simplified example that shows the structure of methods of a typical class and trait in my app:
class demo
{
public function MethodA()
{
return 'method A from class';
}
public function MethodC()
{
return 'method C from class';
}
public function MethodE()
{
return 'method E from class';
}
use tGeneric;
}
trait tGeneric
{
public function MethodA()
{
return 'method A from trait';
}
public function MethodB()
{
return 'method B from trait';
}
public function MethodD()
{
return 'method D from trait';
}
public function MethodE()
{
return 'method E from trait';
}
}
Per the precedence rules listed in the PHP manual:
The precedence order is that methods from the current class override Trait methods, which in turn override methods from the base class.
this is behaving as expected because the output from this code:
$object = new demo();
$array = [
$object->MethodA(),
$object->MethodB(),
$object->MethodC(),
$object->MethodD(),
$object->MethodE()
];
$br = '<br>';
$msg = '';
foreach ($array as $value):
$msg .= $value . $br;
endforeach;
echo $msg . $br;
is:
The methods in the class demo
that override the trait methods from tGeneric
are MethodA() and MethodE(). Is there a way to programmatically generate an array of just these methods in the class that override the methods from the trait?
I have experimented with reflection but the GetMethods()
method retrieves all methods for a class, regardless of whether they originated in the class or were obtained via the use of a trait.
This code:
$rc = new ReflectionClass('demo');
$d = $rc->GetMethods();
$traits = class_uses('demo');
foreach ($traits as $trait):
$reflection = new ReflectionClass($trait);
$t = $reflection->GetMethods();
endforeach;
DisplayInfo($d);
DisplayInfo($t);
function DisplayInfo($array)
{
$br = '<br>';
echo '<b>' . $array[0]->class . '</b>' . $br;
foreach ($array as $value):
echo $value->name . $br;
endforeach;
echo $br;
}
gives this output:
php
I'm trying to generate an array of methods in a class that override trait methods. Here is a simplified example that shows the structure of methods of a typical class and trait in my app:
class demo
{
public function MethodA()
{
return 'method A from class';
}
public function MethodC()
{
return 'method C from class';
}
public function MethodE()
{
return 'method E from class';
}
use tGeneric;
}
trait tGeneric
{
public function MethodA()
{
return 'method A from trait';
}
public function MethodB()
{
return 'method B from trait';
}
public function MethodD()
{
return 'method D from trait';
}
public function MethodE()
{
return 'method E from trait';
}
}
Per the precedence rules listed in the PHP manual:
The precedence order is that methods from the current class override Trait methods, which in turn override methods from the base class.
this is behaving as expected because the output from this code:
$object = new demo();
$array = [
$object->MethodA(),
$object->MethodB(),
$object->MethodC(),
$object->MethodD(),
$object->MethodE()
];
$br = '<br>';
$msg = '';
foreach ($array as $value):
$msg .= $value . $br;
endforeach;
echo $msg . $br;
is:
The methods in the class demo
that override the trait methods from tGeneric
are MethodA() and MethodE(). Is there a way to programmatically generate an array of just these methods in the class that override the methods from the trait?
I have experimented with reflection but the GetMethods()
method retrieves all methods for a class, regardless of whether they originated in the class or were obtained via the use of a trait.
This code:
$rc = new ReflectionClass('demo');
$d = $rc->GetMethods();
$traits = class_uses('demo');
foreach ($traits as $trait):
$reflection = new ReflectionClass($trait);
$t = $reflection->GetMethods();
endforeach;
DisplayInfo($d);
DisplayInfo($t);
function DisplayInfo($array)
{
$br = '<br>';
echo '<b>' . $array[0]->class . '</b>' . $br;
foreach ($array as $value):
echo $value->name . $br;
endforeach;
echo $br;
}
gives this output:
php
php
asked Dec 28 '18 at 14:47
knot22knot22
5091722
5091722
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
You could make almost sure a method overrides a trait method by comparing:
- their file names
(ReflectionFunctionAbstract::getFileName
), - and their start lines (
ReflectionFunctionAbstract::getStartLine
)
Condition
if ($class_method->getFileName() !== $trait_method->getFileName()
|| $class_method->getStartLine() !== $trait_method->getStartLine()) {
$methods_overridden = $class_method->getName();
}
(of course, they also need to have the same name)
Full function
/**
* Given a class name, retrieves the corresponding class' methods that override
* trait methods.
*
* @param string $class_name
* @return ReflectionMethod
* @throws ReflectionException
*/
function getMethodsOverriddenFromTraits(string $class_name): array
{
$class = new ReflectionClass($class_name);
// Retrieve trait methods
$trait_methods = ;
foreach ($class->getTraits() as $trait) {
foreach ($trait->getMethods() as $trait_method) {
$trait_methods[$trait_method->getName()] = $trait_method;
}
}
// Compute class methods that override them
$methods_overridden = ;
foreach ($class->getMethods() as $class_method) {
if (array_key_exists($class_method->getName(), $trait_methods)) {
$trait_method = $trait_methods[$class_method->getName()];
if ($class_method->getFileName() !== $trait_method->getFileName()
|| $class_method->getStartLine() !== $trait_method->getStartLine()) {
$methods_overridden = $class_method->getName();
}
}
}
return $methods_overridden;
}
Demo here: https://3v4l.org/EcFIC
In my app the classes and traits are in separate files, unlike the simplified example I provided in the original post. So is there any reason to include thegetStartLine
method in the condition that determines class methods that override trait methods in the code for the app? Just want to make sure I'm not overlooking something. My assumption is thatgetStartLine
was included in your solution for this post so the original example would work correctly in the demo you provided...is that correct?
– knot22
Dec 28 '18 at 19:35
1
@knot22 That's exactly right. The idea is to have it work in as many different cases as possible, but you can omit the start line condition if your traits are always in distinct files.
– Jeto
Dec 28 '18 at 19:40
OK, excellent. Another thing in your solution I'm wondering about, that I haven't seen before, is thefunction getMethodsOverriddenFromTraits(string $class_name): array
- specifically the: array
part. Googling did not help me find an answer for the purpose of: array
. What does that do?
– knot22
Dec 28 '18 at 19:44
1
It's the PHP7 way of stating what the function will return (unfortunately, you can't be more specific thanarray
). You can omit it without any issues if you're not running PHP7 or if your other functions/methods don't use that syntax. See the docs for more info.
– Jeto
Dec 28 '18 at 19:46
1
A leading backslash before a class name means you're looking for a class of that name that exists within the default (root) namespace, such asReflectionClass
and any other class that is defined by PHP's standard library. If you omit it, PHP will look for the class in the current namespace. So for instance if you addnamespace MyGreatApp;
on top of your code, then referencingReflectionClass
without it will fail because it will look forMyGreatAppReflectionClass
. Hope this makes sense.
– Jeto
Dec 28 '18 at 19:55
|
show 2 more comments
One possible solution would be more applicable if it was more a real code scenario where your traits and classes where in individual files - which should be how you code anyway (IMHO)...
So I put the trait code in a file (I've called it TraitTest.php). Then in my main script is the rest of the code you have, but of course using require_once 'TraitTest.php';
. Then in the DisplayInfo()
function, I've just added the value of getFileName()
, which shows the filename where the method is defined...
function DisplayInfo($array)
{
$br = PHP_EOL;
echo '<b>' . $array[0]->class . '</b>' . $br;
foreach ($array as $value) {
echo $value->getFileName()."->".$value->name . $br;
}
echo $br;
}
which shows...
<b>demo</b>
/home/nigel/workspace2/Test/t1.php->MethodA
/home/nigel/workspace2/Test/t1.php->MethodC
/home/nigel/workspace2/Test/t1.php->MethodE
/home/nigel/workspace2/Test/TraitTest.php->MethodB
/home/nigel/workspace2/Test/TraitTest.php->MethodD
<b>TraitTest</b>
/home/nigel/workspace2/Test/TraitTest.php->MethodA
/home/nigel/workspace2/Test/TraitTest.php->MethodB
/home/nigel/workspace2/Test/TraitTest.php->MethodD
/home/nigel/workspace2/Test/TraitTest.php->MethodE
As you can see, MethodB
is showing up as being defined in TraitTest.php
.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53960295%2fprogrammatically-identify-methods-that-override-trait-methods%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You could make almost sure a method overrides a trait method by comparing:
- their file names
(ReflectionFunctionAbstract::getFileName
), - and their start lines (
ReflectionFunctionAbstract::getStartLine
)
Condition
if ($class_method->getFileName() !== $trait_method->getFileName()
|| $class_method->getStartLine() !== $trait_method->getStartLine()) {
$methods_overridden = $class_method->getName();
}
(of course, they also need to have the same name)
Full function
/**
* Given a class name, retrieves the corresponding class' methods that override
* trait methods.
*
* @param string $class_name
* @return ReflectionMethod
* @throws ReflectionException
*/
function getMethodsOverriddenFromTraits(string $class_name): array
{
$class = new ReflectionClass($class_name);
// Retrieve trait methods
$trait_methods = ;
foreach ($class->getTraits() as $trait) {
foreach ($trait->getMethods() as $trait_method) {
$trait_methods[$trait_method->getName()] = $trait_method;
}
}
// Compute class methods that override them
$methods_overridden = ;
foreach ($class->getMethods() as $class_method) {
if (array_key_exists($class_method->getName(), $trait_methods)) {
$trait_method = $trait_methods[$class_method->getName()];
if ($class_method->getFileName() !== $trait_method->getFileName()
|| $class_method->getStartLine() !== $trait_method->getStartLine()) {
$methods_overridden = $class_method->getName();
}
}
}
return $methods_overridden;
}
Demo here: https://3v4l.org/EcFIC
In my app the classes and traits are in separate files, unlike the simplified example I provided in the original post. So is there any reason to include thegetStartLine
method in the condition that determines class methods that override trait methods in the code for the app? Just want to make sure I'm not overlooking something. My assumption is thatgetStartLine
was included in your solution for this post so the original example would work correctly in the demo you provided...is that correct?
– knot22
Dec 28 '18 at 19:35
1
@knot22 That's exactly right. The idea is to have it work in as many different cases as possible, but you can omit the start line condition if your traits are always in distinct files.
– Jeto
Dec 28 '18 at 19:40
OK, excellent. Another thing in your solution I'm wondering about, that I haven't seen before, is thefunction getMethodsOverriddenFromTraits(string $class_name): array
- specifically the: array
part. Googling did not help me find an answer for the purpose of: array
. What does that do?
– knot22
Dec 28 '18 at 19:44
1
It's the PHP7 way of stating what the function will return (unfortunately, you can't be more specific thanarray
). You can omit it without any issues if you're not running PHP7 or if your other functions/methods don't use that syntax. See the docs for more info.
– Jeto
Dec 28 '18 at 19:46
1
A leading backslash before a class name means you're looking for a class of that name that exists within the default (root) namespace, such asReflectionClass
and any other class that is defined by PHP's standard library. If you omit it, PHP will look for the class in the current namespace. So for instance if you addnamespace MyGreatApp;
on top of your code, then referencingReflectionClass
without it will fail because it will look forMyGreatAppReflectionClass
. Hope this makes sense.
– Jeto
Dec 28 '18 at 19:55
|
show 2 more comments
You could make almost sure a method overrides a trait method by comparing:
- their file names
(ReflectionFunctionAbstract::getFileName
), - and their start lines (
ReflectionFunctionAbstract::getStartLine
)
Condition
if ($class_method->getFileName() !== $trait_method->getFileName()
|| $class_method->getStartLine() !== $trait_method->getStartLine()) {
$methods_overridden = $class_method->getName();
}
(of course, they also need to have the same name)
Full function
/**
* Given a class name, retrieves the corresponding class' methods that override
* trait methods.
*
* @param string $class_name
* @return ReflectionMethod
* @throws ReflectionException
*/
function getMethodsOverriddenFromTraits(string $class_name): array
{
$class = new ReflectionClass($class_name);
// Retrieve trait methods
$trait_methods = ;
foreach ($class->getTraits() as $trait) {
foreach ($trait->getMethods() as $trait_method) {
$trait_methods[$trait_method->getName()] = $trait_method;
}
}
// Compute class methods that override them
$methods_overridden = ;
foreach ($class->getMethods() as $class_method) {
if (array_key_exists($class_method->getName(), $trait_methods)) {
$trait_method = $trait_methods[$class_method->getName()];
if ($class_method->getFileName() !== $trait_method->getFileName()
|| $class_method->getStartLine() !== $trait_method->getStartLine()) {
$methods_overridden = $class_method->getName();
}
}
}
return $methods_overridden;
}
Demo here: https://3v4l.org/EcFIC
In my app the classes and traits are in separate files, unlike the simplified example I provided in the original post. So is there any reason to include thegetStartLine
method in the condition that determines class methods that override trait methods in the code for the app? Just want to make sure I'm not overlooking something. My assumption is thatgetStartLine
was included in your solution for this post so the original example would work correctly in the demo you provided...is that correct?
– knot22
Dec 28 '18 at 19:35
1
@knot22 That's exactly right. The idea is to have it work in as many different cases as possible, but you can omit the start line condition if your traits are always in distinct files.
– Jeto
Dec 28 '18 at 19:40
OK, excellent. Another thing in your solution I'm wondering about, that I haven't seen before, is thefunction getMethodsOverriddenFromTraits(string $class_name): array
- specifically the: array
part. Googling did not help me find an answer for the purpose of: array
. What does that do?
– knot22
Dec 28 '18 at 19:44
1
It's the PHP7 way of stating what the function will return (unfortunately, you can't be more specific thanarray
). You can omit it without any issues if you're not running PHP7 or if your other functions/methods don't use that syntax. See the docs for more info.
– Jeto
Dec 28 '18 at 19:46
1
A leading backslash before a class name means you're looking for a class of that name that exists within the default (root) namespace, such asReflectionClass
and any other class that is defined by PHP's standard library. If you omit it, PHP will look for the class in the current namespace. So for instance if you addnamespace MyGreatApp;
on top of your code, then referencingReflectionClass
without it will fail because it will look forMyGreatAppReflectionClass
. Hope this makes sense.
– Jeto
Dec 28 '18 at 19:55
|
show 2 more comments
You could make almost sure a method overrides a trait method by comparing:
- their file names
(ReflectionFunctionAbstract::getFileName
), - and their start lines (
ReflectionFunctionAbstract::getStartLine
)
Condition
if ($class_method->getFileName() !== $trait_method->getFileName()
|| $class_method->getStartLine() !== $trait_method->getStartLine()) {
$methods_overridden = $class_method->getName();
}
(of course, they also need to have the same name)
Full function
/**
* Given a class name, retrieves the corresponding class' methods that override
* trait methods.
*
* @param string $class_name
* @return ReflectionMethod
* @throws ReflectionException
*/
function getMethodsOverriddenFromTraits(string $class_name): array
{
$class = new ReflectionClass($class_name);
// Retrieve trait methods
$trait_methods = ;
foreach ($class->getTraits() as $trait) {
foreach ($trait->getMethods() as $trait_method) {
$trait_methods[$trait_method->getName()] = $trait_method;
}
}
// Compute class methods that override them
$methods_overridden = ;
foreach ($class->getMethods() as $class_method) {
if (array_key_exists($class_method->getName(), $trait_methods)) {
$trait_method = $trait_methods[$class_method->getName()];
if ($class_method->getFileName() !== $trait_method->getFileName()
|| $class_method->getStartLine() !== $trait_method->getStartLine()) {
$methods_overridden = $class_method->getName();
}
}
}
return $methods_overridden;
}
Demo here: https://3v4l.org/EcFIC
You could make almost sure a method overrides a trait method by comparing:
- their file names
(ReflectionFunctionAbstract::getFileName
), - and their start lines (
ReflectionFunctionAbstract::getStartLine
)
Condition
if ($class_method->getFileName() !== $trait_method->getFileName()
|| $class_method->getStartLine() !== $trait_method->getStartLine()) {
$methods_overridden = $class_method->getName();
}
(of course, they also need to have the same name)
Full function
/**
* Given a class name, retrieves the corresponding class' methods that override
* trait methods.
*
* @param string $class_name
* @return ReflectionMethod
* @throws ReflectionException
*/
function getMethodsOverriddenFromTraits(string $class_name): array
{
$class = new ReflectionClass($class_name);
// Retrieve trait methods
$trait_methods = ;
foreach ($class->getTraits() as $trait) {
foreach ($trait->getMethods() as $trait_method) {
$trait_methods[$trait_method->getName()] = $trait_method;
}
}
// Compute class methods that override them
$methods_overridden = ;
foreach ($class->getMethods() as $class_method) {
if (array_key_exists($class_method->getName(), $trait_methods)) {
$trait_method = $trait_methods[$class_method->getName()];
if ($class_method->getFileName() !== $trait_method->getFileName()
|| $class_method->getStartLine() !== $trait_method->getStartLine()) {
$methods_overridden = $class_method->getName();
}
}
}
return $methods_overridden;
}
Demo here: https://3v4l.org/EcFIC
edited Dec 28 '18 at 16:09
answered Dec 28 '18 at 15:51
JetoJeto
5,03521018
5,03521018
In my app the classes and traits are in separate files, unlike the simplified example I provided in the original post. So is there any reason to include thegetStartLine
method in the condition that determines class methods that override trait methods in the code for the app? Just want to make sure I'm not overlooking something. My assumption is thatgetStartLine
was included in your solution for this post so the original example would work correctly in the demo you provided...is that correct?
– knot22
Dec 28 '18 at 19:35
1
@knot22 That's exactly right. The idea is to have it work in as many different cases as possible, but you can omit the start line condition if your traits are always in distinct files.
– Jeto
Dec 28 '18 at 19:40
OK, excellent. Another thing in your solution I'm wondering about, that I haven't seen before, is thefunction getMethodsOverriddenFromTraits(string $class_name): array
- specifically the: array
part. Googling did not help me find an answer for the purpose of: array
. What does that do?
– knot22
Dec 28 '18 at 19:44
1
It's the PHP7 way of stating what the function will return (unfortunately, you can't be more specific thanarray
). You can omit it without any issues if you're not running PHP7 or if your other functions/methods don't use that syntax. See the docs for more info.
– Jeto
Dec 28 '18 at 19:46
1
A leading backslash before a class name means you're looking for a class of that name that exists within the default (root) namespace, such asReflectionClass
and any other class that is defined by PHP's standard library. If you omit it, PHP will look for the class in the current namespace. So for instance if you addnamespace MyGreatApp;
on top of your code, then referencingReflectionClass
without it will fail because it will look forMyGreatAppReflectionClass
. Hope this makes sense.
– Jeto
Dec 28 '18 at 19:55
|
show 2 more comments
In my app the classes and traits are in separate files, unlike the simplified example I provided in the original post. So is there any reason to include thegetStartLine
method in the condition that determines class methods that override trait methods in the code for the app? Just want to make sure I'm not overlooking something. My assumption is thatgetStartLine
was included in your solution for this post so the original example would work correctly in the demo you provided...is that correct?
– knot22
Dec 28 '18 at 19:35
1
@knot22 That's exactly right. The idea is to have it work in as many different cases as possible, but you can omit the start line condition if your traits are always in distinct files.
– Jeto
Dec 28 '18 at 19:40
OK, excellent. Another thing in your solution I'm wondering about, that I haven't seen before, is thefunction getMethodsOverriddenFromTraits(string $class_name): array
- specifically the: array
part. Googling did not help me find an answer for the purpose of: array
. What does that do?
– knot22
Dec 28 '18 at 19:44
1
It's the PHP7 way of stating what the function will return (unfortunately, you can't be more specific thanarray
). You can omit it without any issues if you're not running PHP7 or if your other functions/methods don't use that syntax. See the docs for more info.
– Jeto
Dec 28 '18 at 19:46
1
A leading backslash before a class name means you're looking for a class of that name that exists within the default (root) namespace, such asReflectionClass
and any other class that is defined by PHP's standard library. If you omit it, PHP will look for the class in the current namespace. So for instance if you addnamespace MyGreatApp;
on top of your code, then referencingReflectionClass
without it will fail because it will look forMyGreatAppReflectionClass
. Hope this makes sense.
– Jeto
Dec 28 '18 at 19:55
In my app the classes and traits are in separate files, unlike the simplified example I provided in the original post. So is there any reason to include the
getStartLine
method in the condition that determines class methods that override trait methods in the code for the app? Just want to make sure I'm not overlooking something. My assumption is that getStartLine
was included in your solution for this post so the original example would work correctly in the demo you provided...is that correct?– knot22
Dec 28 '18 at 19:35
In my app the classes and traits are in separate files, unlike the simplified example I provided in the original post. So is there any reason to include the
getStartLine
method in the condition that determines class methods that override trait methods in the code for the app? Just want to make sure I'm not overlooking something. My assumption is that getStartLine
was included in your solution for this post so the original example would work correctly in the demo you provided...is that correct?– knot22
Dec 28 '18 at 19:35
1
1
@knot22 That's exactly right. The idea is to have it work in as many different cases as possible, but you can omit the start line condition if your traits are always in distinct files.
– Jeto
Dec 28 '18 at 19:40
@knot22 That's exactly right. The idea is to have it work in as many different cases as possible, but you can omit the start line condition if your traits are always in distinct files.
– Jeto
Dec 28 '18 at 19:40
OK, excellent. Another thing in your solution I'm wondering about, that I haven't seen before, is the
function getMethodsOverriddenFromTraits(string $class_name): array
- specifically the : array
part. Googling did not help me find an answer for the purpose of : array
. What does that do?– knot22
Dec 28 '18 at 19:44
OK, excellent. Another thing in your solution I'm wondering about, that I haven't seen before, is the
function getMethodsOverriddenFromTraits(string $class_name): array
- specifically the : array
part. Googling did not help me find an answer for the purpose of : array
. What does that do?– knot22
Dec 28 '18 at 19:44
1
1
It's the PHP7 way of stating what the function will return (unfortunately, you can't be more specific than
array
). You can omit it without any issues if you're not running PHP7 or if your other functions/methods don't use that syntax. See the docs for more info.– Jeto
Dec 28 '18 at 19:46
It's the PHP7 way of stating what the function will return (unfortunately, you can't be more specific than
array
). You can omit it without any issues if you're not running PHP7 or if your other functions/methods don't use that syntax. See the docs for more info.– Jeto
Dec 28 '18 at 19:46
1
1
A leading backslash before a class name means you're looking for a class of that name that exists within the default (root) namespace, such as
ReflectionClass
and any other class that is defined by PHP's standard library. If you omit it, PHP will look for the class in the current namespace. So for instance if you add namespace MyGreatApp;
on top of your code, then referencing ReflectionClass
without it will fail because it will look for MyGreatAppReflectionClass
. Hope this makes sense.– Jeto
Dec 28 '18 at 19:55
A leading backslash before a class name means you're looking for a class of that name that exists within the default (root) namespace, such as
ReflectionClass
and any other class that is defined by PHP's standard library. If you omit it, PHP will look for the class in the current namespace. So for instance if you add namespace MyGreatApp;
on top of your code, then referencing ReflectionClass
without it will fail because it will look for MyGreatAppReflectionClass
. Hope this makes sense.– Jeto
Dec 28 '18 at 19:55
|
show 2 more comments
One possible solution would be more applicable if it was more a real code scenario where your traits and classes where in individual files - which should be how you code anyway (IMHO)...
So I put the trait code in a file (I've called it TraitTest.php). Then in my main script is the rest of the code you have, but of course using require_once 'TraitTest.php';
. Then in the DisplayInfo()
function, I've just added the value of getFileName()
, which shows the filename where the method is defined...
function DisplayInfo($array)
{
$br = PHP_EOL;
echo '<b>' . $array[0]->class . '</b>' . $br;
foreach ($array as $value) {
echo $value->getFileName()."->".$value->name . $br;
}
echo $br;
}
which shows...
<b>demo</b>
/home/nigel/workspace2/Test/t1.php->MethodA
/home/nigel/workspace2/Test/t1.php->MethodC
/home/nigel/workspace2/Test/t1.php->MethodE
/home/nigel/workspace2/Test/TraitTest.php->MethodB
/home/nigel/workspace2/Test/TraitTest.php->MethodD
<b>TraitTest</b>
/home/nigel/workspace2/Test/TraitTest.php->MethodA
/home/nigel/workspace2/Test/TraitTest.php->MethodB
/home/nigel/workspace2/Test/TraitTest.php->MethodD
/home/nigel/workspace2/Test/TraitTest.php->MethodE
As you can see, MethodB
is showing up as being defined in TraitTest.php
.
add a comment |
One possible solution would be more applicable if it was more a real code scenario where your traits and classes where in individual files - which should be how you code anyway (IMHO)...
So I put the trait code in a file (I've called it TraitTest.php). Then in my main script is the rest of the code you have, but of course using require_once 'TraitTest.php';
. Then in the DisplayInfo()
function, I've just added the value of getFileName()
, which shows the filename where the method is defined...
function DisplayInfo($array)
{
$br = PHP_EOL;
echo '<b>' . $array[0]->class . '</b>' . $br;
foreach ($array as $value) {
echo $value->getFileName()."->".$value->name . $br;
}
echo $br;
}
which shows...
<b>demo</b>
/home/nigel/workspace2/Test/t1.php->MethodA
/home/nigel/workspace2/Test/t1.php->MethodC
/home/nigel/workspace2/Test/t1.php->MethodE
/home/nigel/workspace2/Test/TraitTest.php->MethodB
/home/nigel/workspace2/Test/TraitTest.php->MethodD
<b>TraitTest</b>
/home/nigel/workspace2/Test/TraitTest.php->MethodA
/home/nigel/workspace2/Test/TraitTest.php->MethodB
/home/nigel/workspace2/Test/TraitTest.php->MethodD
/home/nigel/workspace2/Test/TraitTest.php->MethodE
As you can see, MethodB
is showing up as being defined in TraitTest.php
.
add a comment |
One possible solution would be more applicable if it was more a real code scenario where your traits and classes where in individual files - which should be how you code anyway (IMHO)...
So I put the trait code in a file (I've called it TraitTest.php). Then in my main script is the rest of the code you have, but of course using require_once 'TraitTest.php';
. Then in the DisplayInfo()
function, I've just added the value of getFileName()
, which shows the filename where the method is defined...
function DisplayInfo($array)
{
$br = PHP_EOL;
echo '<b>' . $array[0]->class . '</b>' . $br;
foreach ($array as $value) {
echo $value->getFileName()."->".$value->name . $br;
}
echo $br;
}
which shows...
<b>demo</b>
/home/nigel/workspace2/Test/t1.php->MethodA
/home/nigel/workspace2/Test/t1.php->MethodC
/home/nigel/workspace2/Test/t1.php->MethodE
/home/nigel/workspace2/Test/TraitTest.php->MethodB
/home/nigel/workspace2/Test/TraitTest.php->MethodD
<b>TraitTest</b>
/home/nigel/workspace2/Test/TraitTest.php->MethodA
/home/nigel/workspace2/Test/TraitTest.php->MethodB
/home/nigel/workspace2/Test/TraitTest.php->MethodD
/home/nigel/workspace2/Test/TraitTest.php->MethodE
As you can see, MethodB
is showing up as being defined in TraitTest.php
.
One possible solution would be more applicable if it was more a real code scenario where your traits and classes where in individual files - which should be how you code anyway (IMHO)...
So I put the trait code in a file (I've called it TraitTest.php). Then in my main script is the rest of the code you have, but of course using require_once 'TraitTest.php';
. Then in the DisplayInfo()
function, I've just added the value of getFileName()
, which shows the filename where the method is defined...
function DisplayInfo($array)
{
$br = PHP_EOL;
echo '<b>' . $array[0]->class . '</b>' . $br;
foreach ($array as $value) {
echo $value->getFileName()."->".$value->name . $br;
}
echo $br;
}
which shows...
<b>demo</b>
/home/nigel/workspace2/Test/t1.php->MethodA
/home/nigel/workspace2/Test/t1.php->MethodC
/home/nigel/workspace2/Test/t1.php->MethodE
/home/nigel/workspace2/Test/TraitTest.php->MethodB
/home/nigel/workspace2/Test/TraitTest.php->MethodD
<b>TraitTest</b>
/home/nigel/workspace2/Test/TraitTest.php->MethodA
/home/nigel/workspace2/Test/TraitTest.php->MethodB
/home/nigel/workspace2/Test/TraitTest.php->MethodD
/home/nigel/workspace2/Test/TraitTest.php->MethodE
As you can see, MethodB
is showing up as being defined in TraitTest.php
.
answered Dec 28 '18 at 15:28
Nigel RenNigel Ren
25.8k61832
25.8k61832
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53960295%2fprogrammatically-identify-methods-that-override-trait-methods%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown