How do I disable IntelliSense in comments in Visual Studio Code? - php

I'm using Visual Studio Code, mostly to work with PHP. Everytime I hit ., IntelliSense kicks in and offers me PHP globals and functions, starting with $_COOKIE. I usually know what global or function I want, so it's a bit annoying. This even happens when I'm within a comment block (/* ... */ or // ...), which is far more annoying. Most of my time is spent going back and deleting $_COOKIE.
An example (not PHP, but you get the idea):
I've tried disabling it as suggested in the docs:
// Controls if quick suggestions should show up while typing
"editor.quickSuggestions": false,
// Controls if suggestions should be accepted with "Enter" - in addition to "Tab". Helps to avoid ambiguity between inserting new lines and accepting suggestions.
"editor.acceptSuggestionOnEnter": true,
// Controls the delay in ms after which quick suggestions will show up.
"editor.quickSuggestionsDelay": 10000,
// Enable word based suggestions
"editor.wordBasedSuggestions": true
... but this has absolutely no effect whatsoever. I still get the list when I hit the dot. The delay increase from 100 to 1000, too, has no effect.
How do I turn off IntelliSense inside code comments?
How do I disable IntelliSense on hitting . and just have it show up when I hit Ctrl+Space? (See update 2 below)
How do I disable IntelliSense completely, at least for PHP?
Update: As mentioned here, disabling quick suggestions on trigger characters is achieved via:
// Controls if suggestions should automatically show up when typing trigger characters
"editor.suggestOnTriggerCharacters": false
However, the other options mentioned above still don't do anything.
Update 2: It is possible to mess with the . binding by adding this to the keybindings.json file:
{
"key": ".",
"command": "x",
}
However,this results in a warning message at the top of the screen that says "command 'x' not found". If you leave it empty or try to pass null to command, it still doesn't work, as it doesn't overwrite the default key binding. According to the documentation, it's possible to disable a certain action by prefixing it with a -, but this doesn't work for me:
"command": "-^acceptSelectedSuggestion"
or
"command": "-acceptSelectedSuggestion"
In either case, acceptSelectedSuggesdtion isn't really the command that's being executed when I hit ., it's probably more like:
"command": "-editor.action.triggerSuggest"
But this doesn't work either.

Since about March or April 2017, this has been fixed, and also the default has changed to be no auto-complete in comments. The default is:
"editor.quickSuggestions": {
"other": true,
"comments": false,
"strings": false
},
I don't have that explicitly in my settings, and just did a test with a fresh PHP file, and I can type global. then space, and don't get anything auto-completed. (I tried both main code and in comments.) I do see $COOKIE pop up as the first suggestion, but I need to use up/down arrows and then enter to bring it in.
Aha, global. then ENTER does give me global.$COOKIE (even in comments, which is a bit weird). I can fix that with:
"editor.acceptSuggestionOnEnter": "off",
To see other settings you might want to touch, go to the settings page and type "suggestion" in the search box. Each is commented. E.g. "editor.suggestOnTriggerCharacters": false, gets rid of the auto-suggestions completely.
You can also specify the settings for just one language, e.g.
"[php]": {
"editor.suggestOnTriggerCharacters": false,
},

Despite Darren Cook's answer and the docs, the editor.quickSuggestions settings don't do anything for suggestions that pop up due to trigger characters (see this issue on GitHub). These seem to be subject to their own rules. Namely, when typing a trigger character in a string, you never get the suggestions, no matter what you said in editor.quickSuggestions; and when typing a trigger character in a comment or "other", you always get the suggestions, no matter what you said in editor.quickSuggestions.
Thus the only reliable way to get rid of what I'm calling "trigger-character suggestions" (which are by far the most annoying kind!) is to use the setting specifically devoted to it:
"editor.suggestOnTriggerCharacters": false
If someone can leave a comment on how to discover what the trigger characters are, or better yet, how to specify them, I would be all too happy to edit my answer to take this into account.
Note that the suggestions which pop up due to actually matching the characters you type with known modules, variables, functions, etc., are still controlled by editor.quickSuggestions and not by editor.suggestOnTriggerCharacters.

Related

PhpStorm Code Style 'Space - Within - Brackets' not functioning

I am working on a PHP Laravel project with a team that requires spaces within brackets like this:
$t = $one[ 0 ];
I attempted to accomplish this by set the following requirement in the Code Style Preference:
The highlights show that spaces should be added within brackets as needed. However, after saving and restarting, I do not get this style applied, no matter how many time I press Ctrl+Alt+L.
Worse still, PhpStorm strips out the spaces that already exist within brackets, which causes a huge headache when I try to auto format existing code.
So this:
Is reformatted and becomes this:
I've set up other custom code style setting, and the other custom setting are getting applied.
Could someone offer some help with fixing this style problem?
That option works just fine. It is for accessing individual array elements (e.g. $t = $one[ 0 ];).
But on your screenshots, where it does not work... it's array initializer (in other words, $var = array('aaa', 'bbb');)... and for that you need to use appropriate option -- "Array initializer parentheses" (which is just a bit below of what you have tried above).

Is it OK to design code that throws basic warnings, or should I change my code?

with warning, I mean warnings that are not important or breaking, and not wrong code per say.
for example, imagine I have a search page.
$query, $items (as in how many items to display)
and I would still supply the page with only $query, and I would use some default value for $items.
Now, since my code is basically
$query = $_GET["query"];
$items = $_GET["items"];
after this I can write such code to show items,
if (empty($items))
//show default number of items
else
//show set amount of items
Of course I would need to check if items is not number and stuff like that, but the basic idea is this.
This obviously throws warning "items" is not set. To fix this, before doing $items, I can check if "items" exists, and maybe if it exists set it to that amount and if not the default amount. This would throw nothing. However this only makes my code either longer or just the same logic at different place. I would still need to check if $items is number and tons of other stuff anyway, its not only one check either, although it is still short in this case. At best case, I would end with basically same thing in different place.
So what should I do? Make php ignore warnings for error_log ? Or should I make sure this errors never happen even if it doesnt change how the code works and make my "uglier" ?
Are warnings, warnings or just suggestions?
After some research and a bit of thinking, I have written sensible variations of the code above. the solutions always, naturally, include using $_GET or ignoring errors/warnings/notices. this is not ideal.
I thought to see if filter_var would be useful for this, it is not.
I have created several solutions and the most feasible one seems to be having a function for $_GET
example:
function setVar($v){
if (isset($_GET[$v]))
return $_GET[$v];
}
As expected, this will be just a reference to the original variable so nothing is changed. Except it wont throw notices. (isset and such will still work for unset/empty parameters as I dont return anything if it fails anyway) and GET/POST etc. will work in all scopes so I can use this in a "functions.php".
Also on a side note, for php 5.3 and below, it seems you can use(while 5.4 & above causes error)
function x($_GET...
while it is not exactly traditional, I dont think it would be much different to use setVar('var') rather than $_GET['var']

Should you verify parameter types in PHP functions?

I'm used to the habit of checking the type of my parameters when writing functions. Is there a reason for or against this? As an example, would it be good practice to keep the string verification in this code or remove it, and why?
function rmstr($string, $remove) {
if (is_string($string) && is_string($remove)) {
return str_replace($remove, '', $string);
}
return '';
}
rmstr('some text', 'text');
There are times when you may expect different parameter types and run different code for them, in which case the verification is essential, but my question is if we should explicitly check for a type and avoid an error.
Yes, it's fine. However, php is not strongly typed to begin with, so I think this is not very useful in practice.
Additionally, if one uses an object other than string, an exception is a more informative; therefore, I'd try to avoid just returning an empty string at the end, because it's not semantically explaining that calling rmstr(array, object) returns an empty string.
My opinion is that you should perform such verification if you are accepting input from the user. If those strings were not accepted from the user or are sanitized input from the user, then doing verification there is excessive.
As for me, type checking actual to data, getted from user on top level of abstraction, but after that, when You call most of your functions you already should now their type, and don't check it out in every method. It affects performance and readability.
Note: you can add info, which types is allowed to arguments for your functions by phpDoc
It seems local folks understood this question as "Should you verify parameters" where it was "Should you verify parameter types", and made nonsense answers and comments out of it.
Personally I am never checking operand types and never experienced any trouble of it.
It depends which code you produce. If it's actually production code, you should ensure that your function is working properly under any circumstances. This includes checking that parameters contain the data you expect. Otherwise throw an exception or have another form of error handling (which your example is totally missing).
If it's not for production use and you don't need to code defensively, you can ignore anything and follow the garbage-in-garbage-out principle (or the three shit principle: code shit, process shit, get shit).
In the end it is all about matching expectations: If you don't need your function to work properly, you don't need to code it properly. If you are actually relying on your code to work precisely, you even need to validate input data per each unit (function, class).

How do you handle PHP notice (error)

The following code generates a notice if $n is not set. Solving it requires an additional statement (isset($n)) or to "declare" the $n ($n=''). But what consequences does this notice have? The below code is a lot neater and lets say we turn error_reporing off in production no difference is visible frontend. Does something bad follows? Prestanda, readability etc? (sorry for the bad english)
if($n==1){
//do something
}
There is no "consequence" to notices, per sé, other than bad coding practices. You should be coding with error_reporting set to E_ALL on your development machines, so obviously the consequence there is a lot of notices...
I would argue that your code actually isn't neat, because you're testing a variable which doesn't get set previously.
A suggestion would be something like this:
<?php
if (!empty($n) && $n == 1)
{
//do something
}
empty checks for existence automatically (just like calling isset before it) but it also checks to make sure your value doesn't evaluate as false with values like false, 0, or '' (empty string).
A notice means that while your code will work as expected, it isn't written "like it should be". It's like the compiler telling you "I know what you mean here and I can do it, but you shouldn't rely on this. Please write it differently so I don't have to make assumptions".
Therefore a notice by itself doesn't mean that something bad happens most of the time. However, I wouldn't call anyone who accepts notices in their code a professional programmer because fixing the notices is a pretty simple task and not having any notices says that you understand the language's basics well. If someone can't or don't want to do even this much, it says something about them.
In your specific example, something like this should be done:
$n = null; // or some other appropriate initial value
// possibly change the value of $n here
if($n==1) {
//do something
}
Note that by writing the extra $n = null, you are not making the program any different as far as the compiler is concerned (it will end up doing that itself at the same time it gives out the notice anyway). But you are making it very different as far as someone reading the code is concerned: with this code they won't have a "WTF did this $n come from???" moment.
Normally in the production environments all error reporting which come strait from PHP libraries is turned off or parsed before showing to end user (it`s still logged).
There are no consequences in notice, it`s just notice to developer that something bad could happen in this place, in your example initializing the variable with value.
I encountered one function that handling "PHP Notice" can be beneficial.
The function is:
geoip_record_by_name()
This function return "false" and send "PHP Notice" on IP's that do not find in its database.
The standard is that IP's reserved for internal networks, or Localhost will not be found.
As a horrible practice this function treat this normal condition as bed coding. WRRRRR!!!
There is solution to filter local IP,s before sending to this function ( assuming that all other addresses are covered by geoip database).
I consider this geoip_record_by_name() as pest function that handling of "PHP Notice" is justified.
Discussion related to this pest function

Find where a variable is defined in PHP (And/or SMARTY)?

I'm currently working on a very large project, and am under a lot of pressure to finish it soon, and I'm having a serious problem. The programmer who wrote this last defined variables in a very odd way - the config variables aren't all in the same file, they're spread out across the entire project of over 500 files and 100k+ lines of code, and I'm having a hell of a time figuring out where a certain variable is, so I can fix an issue.
Is there a way to track this variable down? I believe he's using SMARTY (Which I can not stand, due to issues like this), and the variable is a template variable. I'm fairly sure that the variable I'm looking for was initially defined as a PHP variable, then that variable is passed into SMARTY, so I'd like to track down the PHP one, however if that's impossible - how can I track down where he defined the variable for SMARTY?
P.S. I'm in Vista, and don't have ssh access to the server, so 'grep' is out of the question.
Brute force way, because sometimes smarty variables are not directly assigned, but their names can be stored in variables, concatenated from many strings or be result of some functions, that makes it impossible to find in files by simply searching / greping.
Firstly, write your own function to print readable backtrace, ie:
function print_backtrace()
{
$backtrace = debug_backtrace(FALSE);
foreach($backtrace as $trace)
echo "{$trace['file']} :: {$trace['line']}<br>";
}
Open main smarty file (Smarty.class.php by default) and around line 580 there is function called assign. Modify it to watch for desired variable name:
function assign($tpl_var, $value = null)
{
if($tpl_var == 'FOOBAR') /* Searching for FOOBAR */
{
print_backtrace();
exit;
}
The same modification may be required for second function - assign_by_ref. Now after running script you should have output like that:
D:\www\test_proj\libs\smarty\Smarty.class.php :: 584
D:\www\test_proj\classes.php :: 11
D:\www\test_proj\classes.php :: 6
D:\www\test_proj\functions.php :: 7
D:\www\test_proj\index.php :: 100
Second line points to the place where variable was first assigned.
This sort of thing is the #1 reason I install Cygwin on all my windows machines.
grep myvariablename `find project_dir -name "*.php"`
I can't imagine programming without a working grep.
There is an interesting further option, ugly like hell but helpful if you are really lost.
If you would like to know where THE_NAME was defined, write lines like these on a place you are sure is run first:
error_reporting(E_ALL);
define('THE_NAME', 'Chuck Norris');
If later PHP will run the definition you are looking for, it will write a notice like this:
Notice: Constant THE_NAME already defined
in /home/there/can-rip-a-page-out-of-facebook.com/SomeConfiguration.php on line 89
Then you know that the definition you are looking for is in the file SomeConfiguration.php on line 89.
To have this working, you must consider
if there are HTTP forwards in the framework on the way to the code you set in
if there are further commands setting the PHP error reporting mode
So sometimes it helps to add some exit('here') in order not to blur the output. Maybe you have to narrow down a bit or you have to set error_reporting earlier, but you'll find it.
It's not a perfect solution, but I find agent ransack useful for searching large directories and files. Might help you narrow things down. The search results will allow you to read the exact line it finds a match on in the result pane.
If you use the netbeans editor just "right click" -> "go to Definition"
Or ctrl + click on the variable.
If the editor can't figure it out, you could fallback to the "Find in files" option.
Just use one of the available PHP IDEs (or a simple text editor like Notepad++ if you're really desperate) and search for the name of the variable in all source files (most PHP IDEs also support finding where functions/vars were defined and allow you to jump to the relevant piece of code). Though it seems weird that you don't know what piece of code calls the template (whether it's Smarty or anything else doesn't really matter). You should be able to drill down in the code starting from the URI (using any IDE which supports debugging), because that way you're bound to see where said variable is defined.

Categories