I was wondering if there is a way to force phpDocumentor to print out the potential methods you could use for getting and setting when you do them dynamically with a __call().
In the case of my simple getter, I would want it to cycle through all private variables and just append get to them (and uppercase the first letter, of course).
See the phpDocumentor reference on #method.
Related
Essentially, I seek to pass a static class method to a callback, but do not wish to do so using a hard-coded string, but rather the fully-qualified class method literal. We can do that using classes like so:
$name = NS\FooClass::class;
instead of:
$name = 'NS\FooClass';
which will give us the string of the fully-qualified name of the class. I seek to be able to do something similar for a class method like so:
$name = NS\FooClass::foo_method::method;
instead of:
$name = 'NS\FooClass::foo_method';
It is more manageable and I can use the IDE functionality way better using the literals. Any similar way I can achieve what I want with the class methods without using strings?
There is currently no such mechanism built into the language. It has been suggested - see for instance this discussion from Feb 2020 - but there are more nuances to think about than might be immediately apparent; notably:
Should the syntax resolve at run-time and check the existence of the class and the method (::class in most cases doesn't; a bare function like strlen::func would have to because of the way namespaces resolve; an object implementing __callStatic could never be used this way)?
Should the result be a string, an array (see below), or a Closure object?
Anyway, that's a topic for elsewhere...
As the manual page on the callable type says, there are two ways to specify a static method for use as a callback:
As a string, as in your example 'NS\FooClass::foo_method'
As an array where the first part is a class name, and the second part is a the method name: ['NS\FooClass', 'foo_method']
Since only the class name needs to be qualified with namespace information, you can use ::class with the second syntax to get nearly what you wanted:
$callback = [NS\FooClass::class, 'foo_method'];
This allows any decent IDE to spot the reference to the class, and allows you to reference it by an imported or aliased name.
It's worth noting that if the callable type is specified in a parameter or return type declaration or a docblock, some IDEs (e.g. PhpStorm) will "understand" either format as a reference to the method, and include it in features like "find usages" and "go to declaration".
While looking over various PHP libraries I've noticed that a lot of people choose to prefix some class methods with a single underscore, such as
public function _foo()
...instead of...
public function foo()
I realize that ultimately this comes down to personal preference, but I was wondering if anyone had some insight into where this habit comes from.
My thought is that it's probably being carried over from PHP 4, before class methods could be marked as protected or private, as a way of implying "do not call this method from outside the class". However, it also occurred to me that maybe it originates somewhere (a language) I'm not familiar with or that there may be good reasoning behind it that I would benefit from knowing.
Any thoughts, insights and/or opinions would be appreciated.
It's from the bad old days of Object Oriented PHP (PHP 4). That implementation of OO was pretty bad, and didn't include things like private methods. To compensate, PHP developers prefaced methods that were intended to be private with an underscore. In some older classes you'll see /**private*/ __foo() { to give it some extra weight.
I've never heard of developers prefacing all their methods with underscores, so I can't begin to explain what causes that.
I believe the most authoritative source for these kinds of conventions for PHP right now would be the PSR-2: Coding Style Guide because the Zend Framework is part of PSR:
Property names SHOULD NOT be prefixed with a single underscore to indicate protected or private visibility.
Now, in 2013, this is "officially" bad style by the PSR-2 coding guideline:
Property names SHOULD NOT be prefixed with a single underscore to indicate protected or private visibility`
Source: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
I was strongly against prefixing private/protected methods with underscore since you can use private/protected keyword for that and IDE will mark it for you.
And I still am, but, I found one reason why it can be a good practice. Imagine that you have public method addFoo() and inside that method you have some part of task which is common with other methods addFooWhenBar(), addFooWhenBaz()... Now, best name for that common method would be addFoo(), but it is already taken, so you must come up with some ugly name like addFooInternal() or addFooCommon() or ... but _addFoo() private method looks like best one.
Leading underscores are generally used for private properties and methods. Not a technique that I usually employ, but does remain popular among some programmers.
I use a leading underscore in the PHP 5 class I write for private methods. It's a small visual cue to the developer that a particular class member is private. This type of hinting isn't as useful when using an IDE that distinguishes public and private members for you. I picked it up from my C# days. Old habits...
I was looking for the same answer, I did some research, and I've just discovered that php frameworks suggest different styles:
Code Igniter
The official manual has a coding style section that encourages this practice:
Private Methods and Variables
Methods and variables that are only accessed internally, such as utility and helper functions that your public methods use for code abstraction, should be prefixed with an underscore.
public function convert_text()
private function _convert_text()
Other frameworks do the same, like
Cakephp:
does the same:
Member Visibility
Use PHP5’s private and protected keywords for methods and variables. Additionally, non-public method or variable names start with a single underscore (_). Example:
class A
{
protected $_iAmAProtectedVariable;
protected function _iAmAProtectedMethod()
{
/* ... */
}
private $_iAmAPrivateVariable;
private function _iAmAPrivateMethod()
{
/* ... */
}
}
And also
PEAR
does the same:
Private class members are preceded by a single underscore. For example:
$_status _sort() _initTree()
While
Drupal
code style specifically warns against this:
Protected or private properties and methods should not use an underscore prefix.
Symphony
on the other hand, declares:
Symfony follows the standards defined in the PSR-0, PSR-1, PSR-2 and PSR-4 documents.
I believe your original assumption was correct, I have found it to be common practice for some languages to prefix an underscore to methods/members etc that are meant to be kept private to the "object". Just a visual way to say although you can, you shouldn't be calling this!
I know it from python, where prefixing your variables with an underscore causes the compiler to translate some random sequence of letters and numbers in front of the actual variable name.
This means that any attempt to access the variable from outside the class would result in a "variable undefined" error.
I don't know if this is still the convention to use in python, though
In Drupal (a php CMS) underscores can be used to prevent hooks from being called (https://api.drupal.org/api/drupal/includes!module.inc/group/hooks/7).
If I have a module called "my_module" and want to name a function my_module_insert it would "hook" on the function hook_insert. To prevent that I can rename my function to _my_module_insert.
ps
The way hooks works in Drupal it's possible to implement a hook by mistake, which is very bad.
Drupal, and using underscore:
In a general way the underscore is to simple mark the fact that a function would probably only be called by a related parent function...
function mymodule_tool($sting="page title"){
$out ='';
//do stuff
$out .= _mymodule_tool_decor($sting);
return $out;
}
function _mymodule_tool_decor($sting){
return '<h1>'.$string.'</h1>';
}
Of course, just a simple example...
Using underscore in just for remembering purpose that we will not 'modify the variable'/'call the function' outside the class.
As we declare const variables in all uppercase so that while seeing the name of variable can guess that it is a const variable. Similar the variable that we don't want to modify outside the class, we declare it with underscore for our own convention.
That means that this method is private.
"I realize that ultimately this comes down to personal preference, but I was wondering if anyone had some insight into where this habit comes from." - it shouldn't be personal preference because every language or framework has it's own coding standards. Some FW coding standards is starting private methods with an _ and some FW discourage that.
You shoud use coding standard of a FW in which you program. To check if your code is according to the coding standard, you have a tool PHP_CodeSniffer: https://github.com/squizlabs/PHP_CodeSniffer
Very useful, detects errors regarding coding standard.
They are called "magic methods".
My question is rather simple, here is the context:
http://php.net/manual/en/language.oop5.magic.php
Magic Methods
The function names __construct(), __destruct(), __call(),
__callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state() and __clone() are magical in PHP classes. You cannot have functions with these names in
any of your classes unless you want the magic functionality associated
with them.
PHP reserves all function names starting with __ as magical. It is recommended that you do not use function names with __ in PHP unless you want some documented magic functionality.
I get what these methods are for and how to use them. What I don't understand is this:
...unless you want some documented magic functionality.
What does that even mean? Are there actual reasons to create user defined __magicMethods()?
I think that they only mean that it's better not to use __ as a starting name for your methods because PHP has reserved that convention for his magic methods and if you do use that for a method it might get overriden in the future and have some magic functionality. At least that's how i understood that
EDIT - to be even clearer: Let's say thatyou implement for your own business logic a method called __toNumber(). In a future version of PHP they decide that whenever an object is used as a number (maybe when you do $result = 3 * $yourObject) the magic method __toNumber() will be invoked...your object will have some "Magic" documented functionality even if you didn't specifically add it
It means never use names that starts with __ for functions unless you want the magic functionality documented in the PHP manual.
I have some code I'm working with that was written by the guy before me and I'm trying to look it over and get a feel for the system and how it all works. I am also fairly new to PHP, so I have a few questions for those willing and able to provide.
The basic breakdown of the code in question is this:
$__CMS_CONN__ = new PDO(DB_DSN, DB_USER, DB_PASS);
Record::connection($__CMS_CONN__);
First question, I know the double underscore makes it magic, but I haven't been able to find anywhere exactly what properties that extends to it, beyond that it behaves like a constant, kind of. So what does that mean?
class Record
{
public static $__CONN__ = false;
final public static function connection($connection)
{
self::$__CONN__ = $connection;
}
}
Second, these two pieces go together. They are each in separate files. From what I've read, static variables can be referenced in the same way as static functions, so couldn't you just call the variable and set it directly instead of using the function?
I get the feeling it's more involved than I am aware, but I need to start somewhere.
This isn't a magic variable. The person who wrote that shouldn't really use double underscores for variable names like that because it can cause confusion.
This is just a static property on a class. Which means it is shared between instances of that class (in the same php request).
Have a look at the docs for static properties if you're unsure on how these work.
There are several predefined "magic constants" that use this naming style. However, I don't think the underscores mean anything special (as far as the language is concerned); i.e. defining your own variable like this won't bestow it any magical properties. It may be part of the previous programmer's naming convention, and if so, it's probably ill-advised.
Setting a property via a function can, in many circumstances, make the "client" code more resilient to changes in the implementation of the class. All implementation details can be hidden inside the method (known as a "setter"). However, there are strong feelings about whether this is a good idea or not (I, for one, am not a big fan).
Two underscores do not make a variable magic.
It's better to use getters/setters than to access class properties directly.
The PHP manual has this to say on naming variables (and other symbols) with underscores:
PHP reserves all symbols starting with __ as magical. It is recommended that you do not create symbols starting with __ in PHP unless you want to use documented magical functionality.
Pay particular attention to the use of the words "reserves" and "documented". They mean double underscores shouldn't be used for user-defined symbols as it may lead to future conflicts, and that unless the symbol is explicitly mentioned in the manual as being magic, it's mundane.
I am not really clear about declaring functions in php, so I will give this a try.
getselection();
function getselection($selection,$price)
{
global $getprice;
switch($selection)
{
case1: case 1:
echo "You chose lemondew <br />";
$price=$getprice['lemondew'].'<br>';
echo "The price:".$price;
break;
Please let me know if I am doing this wrong, I want to do this the correct way; in addition, php.net has examples but they are kind of complex for a newb, I guess when I become proficient I will start using their documentation, thank you for not flaming.
Please provide links that might also help me clear this up?
Your example seems valid enough to me.
foo('bar');
function foo($myVar)
{
echo $myVar
}
// Output: bar
See this link for more info on user-defined functions.
You got off to a reasonable start. Now all you need to do is remove the redundant case 1:, close your switch statement with a } and then close your function with another }. I assume the global array $getprice is defined in your code but not shown in the question.
it's good practice to declare functions before calling them. It'll prevent infrequent misbehavior from your code.
The sample is basically a valid function definition (meaning it runs, except for what Asaph mentions about closing braces), but doesn't follow best practices.
Naming conventions: When a name consists of two or more words, use camelCase or underscores_to_delineate_words. Which one you use isn't important, so long as you're consistent. See also Alex's question about PHP naming conventions.
Picking a good name: a "get" prefix denotes a "getter" or "accessor"; any method or function of the form "getThing" should return a thing and have no affects visible outside the function or object. The sample function might be better called "printSelection" or "printItem", since it prints the name and price of the item that was selected.
Globals: Generally speaking, globals cause problems. One alternative is to use classes or objects: make the variable a static member of a class or an instance member of an object. Another alternative is to pass the data as an additional parameter to the function, though a function with too many parameters isn't very readable.
Switches are very useful, but not always the best choice. In the sample, $selection could easily hold the name of an item rather than a number. This points to one alternative to using switches: use an index into an array (which, incidentally, is how it's done in Python). If the cases have the same code but vary in values used, arrays are the way to go. If you're using objects, then polymorphism is the way to go--but that's a topic unto itself.
The $price parameter appears to serve no purpose. If you want your function to return the price, use a return statement.
When you called the function, you neglected to pass any arguments. This will result in warnings and notices, but will run.