I don't know if it's just me or not, but I am allergic to one line ifs in any c like language, I always like to see curly brackets after an if, so instead of
if($a==1)
$b = 2;
or
if($a==1) $b = 2;
I'd like to see
if($a==1){
$b = 2;
}
I guess I can support my preference by arguing that the first one is more prone to errors, and it has less readability.
My problem right now is that I'm working on a code that is packed with these one line ifs, I was wondering if there is some sort of utility that will help me correct these ifs, some sort of php code beautifier that would do this.
I was also thinking of developing some sort of regex that could be used with linux's sed command, to accomplish this, but I'm not sure if that's even possible given that the regex should match one line ifs, and wrap them with curley brackets, so the logic would be to find an if and the conditional statement, and then look for { following the condition, if not found then wrap the next line, or the next set of characters before a line break and then wrap it with { and }
What do you think?
Your best bet is probably to use the built-in PHP tokenizer, and to parse the resulting token stream.
See this answer for more information about the PHP Tokenizer: https://stackoverflow.com/a/5642653/1005039
You can also take a look at a script I wrote to parse PHP source files to fix another common problem in legacy code, namely to fix unquoted array indexes:
https://github.com/GustavBertram/php-array-index-fixer/blob/master/aif.php
The script uses a state machine instead of a generalized parser, but in your case it might be good enough.
Related
I am keeping record of every request made to my website. I am very aware of the security measurements that need to be taken before executing any MySQL query that contains data coming from query strings. I clean it as much as possible from injections and so far all tests have been successful using:
htmlspecialchars, strip_tags, mysqli_real_escape_string.
But on the logs of pages visited I find query strings of failed hack attempts that contain a lot of php code:
?1=%40ini_set%28"display_errors"%2C"0"%29%3B%40set_time_limit%280%29%3B%40set_magic_quotes_runtime%280%29%3Becho%20%27->%7C%27%3Bfile_put_contents%28%24_SERVER%5B%27DOCUMENT_ROOT%27%5D.%27/webconfig.txt.php%27%2Cbase64_decode%28%27PD9waHAgZXZhb
In the previous example we can see:
display_errors, set_time_limit, set_magic_quotes_runtime, file_put_contents
Another example:
/?s=/index/%5Cthink%5Capp/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=ctlpy.php&vars[1][]=<?php #assert($_REQUEST["ysy"]);?>ysydjsjxbei37$
This one is worst, there is even some <?php and $_REQUEST["ysy"] stuff in there. Although I am able to sanitize it, strip tags and encode < or > when I decode the string I can see the type of requests that are being sent.
Is there any way to detect a string that contains php code like:
filter_var($var, FILTER_SANITIZE_PHP);
FYI: This is not a real function, I am trying to give an idea of what I am looking for.
or some sort of function:
function findCode($var){
return ($var contains PHP) ? true : false
}
Again, not real
No need to sanitize, that has been taken care of, just to detect PHP code in a string. I need this because I want to detect them and save them in other logs.
NOTE: NEVER EXECUTE OR EVAL CODE COMING FROM QUERY STRINGS
After reading lots of comments #KIKO Software came up with an ingenious idea by using PHP tokenizer, but it ended up being extremely difficult because the string that is to be analyzed needed to have almost prefect syntax or it would fail.
So the best solution that I came up with is a simple function that tries to find commonly used PHP statements, In my case, especially on query strings with code injection. Another advantage of this solution is that we can modify and add to the list as many PHP statements as we want. Keep in mind that making the list bigger will considerably slow down your script. this functions uses strpos instead of preg_match (regex ) as its proven to perform faster.
This will not find 100% PHP code inside a string, but you can customize it to find as much as is required, never include terms that could be used in regular English, like 'echo' or 'if'
function findInStr($string, $findarray){
$found=false;
for($i=0;$i<sizeof($findarray);$i++){
$res=strpos($string,$findarray[$i]);
if($res !== false){
$found=true;
break;
}
}
return $found;
}
Simply use:
$search_line=array(
'file_put_contents',
'<?=',
'<?php',
'?>',
'eval(',
'$_REQUEST',
'$_POST',
'$_GET',
'$_SESSION',
'$_SERVER',
'exec(',
'shell_exec(',
'invokefunction',
'call_user_func_array',
'display_errors',
'ini_set',
'set_time_limit',
'set_magic_quotes_runtime',
'DOCUMENT_ROOT',
'include(',
'include_once(',
'require(',
'require_once(',
'base64_decode',
'file_get_contents',
'sizeof',
'array('
);
if(findInStr("this has some <?php echo 'PHP CODE' ?>",$search_line)){
echo "PHP found";
}
For example
$var = '10/2';
Is there a way for me to output the value 5 from that easily?
So something like this:
$foo = ($var) + 5;
I want $foo to have a value of 10?
Currently, the best way I know is to explode $var and then divide $var[0] by $var[1]. Is there a quicker way?
Another way of asking; Is there a way to tell the system to treat '10/2' as an equation instead of a string?
Could be you can use a solution like this
$foo = eval('return '.$var +5 .';');
print $foo;
eval require a line of code .. so you could build a valid code line
eval() to either assign in place or return:
eval("\$foo = ($var) + 5;");
$foo = eval("return ($var) + 5;");
First things first, EVAL IS HAZARDOUS AND SHOULD NEVER BE USED UNLESS YOU KNOW WHAT YOU'RE DOING! As an addendum to this, you don't know what you're doing. No matter how experienced you are as a programmer, when it comes to eval just assume you don't know what you're doing. Believe me, in the long run your sanity will thank you.
As for your problem, you're basically asking how to write an equation parser. Writing a full blown one that can handle all cases of valid input (and reliably identify invalid input) is a much bigger job than you might at first think, so if you really do need to parse string equations it may be better to look for a library that will do it for you because the chances are whoever wrote the library thought of a lot of stuff that you didn't, such as handling operator precedence and how parenthesis can modify it, how to pass strings in scientific notation, etc.
One of your comments suggests using PHP Math Parser. I've never personally used it, but I know the author by reputation well enough to believe it's a reliable library.
If your use case is always going to be as simple as your example then you can simply split the string and process the resulting fragments.
$parts = explode ("/", $var);
$foo = $parts[0] / $parts[1];
I have seen some code like below used
$row [0] ['hello'];
or like
$this->function ('abc');
Does leaving space after each string or variable is good coding practice or will it cause any problem any where ?
Only to readers. The parser does not care, except inside strings. These will yield different results:
$array = array(3);
echo "$array [0]\n";
echo "$array[0]\n";
Results will look something like this:
Array [0]
3
I prefer less white space over spacing things out, yet there doesnt seem to be any errors most of the time. But in my opinion, $this->function('abc'); looks nicer than $this->function ('abc');
Good coding practice is correlated with the programming language you are using. Some languages like Ruby or Python might have conflicts with leaving space in between. The syntax might be okay across all languages but I am sure that for Dynamic scripting languages it is best to practice the proper syntax to avoid bugs of any sort. It gets more complex when dealing with other formats of data. For example, JSON data. It is here that the best practice comes into play. For simple arrays it is not too important but for those complex data it will be good to use a standard for clarity sake more than anything.
I think you should use accepted standard psr-2.
From terminal you can use phpcs to check your script: phpcs --standard=PSR2 file.php
"multiple annotations found at this line"
i have been using aptana and other IDE before, but never gave me this error, but yesterday i installed zend studio and it was giving following error in all my code where i have assigned and also check if condition at same time.
code:
line 16: if ($message_array = #unserialize($e->getMessage()))
line 17: $message = $message_array;
on all if condition, where i assigned the value to a variable and also check if the variable is true/false, it gives me error "multiple annotations found at this line"
Yeah, that syntax is typically flagged by most decent IDEs as "Accidental Assignment" (since it's not obvious if you meant = or ==). Most will allow you to wrap it in a () to silence the error (since then it's apparent you want the result rather than a test):
if (($message_array = #unserialize($e->getMessage()))) {
}
Also, for readability and maintainability, I would suggest a few things there.
First, use braces. Since it's only a special case that lets you not use them, I personally think it's better form to always use them so that it's clear what was meant.
Second, do all asignment outside of the if clause. It makes it more explicit and easier to tell at a quick glance what you meant. Plus it looks less cluttered.
$message_array = #unserialize($e->getMessage());
if ($message_array) {
...
}
Third, I would suggest avoiding the # operator. To me it's a sign of code-rot. While I know it's easy to use and easier than properly handling the error, I think it's just a short-cut that will make life harder for you. You can avoid it in a few ways. First, you can check the string before you pass it to unserialize. Make sure it's non-empty, a string, etc. Secondly, you can install an error handler to throw exceptions on PHP errors (what I do). That way, you just wrap the unserialize call in a try {} catch(){} block. It's nicer since you actually can inspect the error rather than just trusting that the thrown error is what you think it is...
That is not an actual error. Instead the IDE has found more than one error, warnings or hints at the same code line.
You can look at the Problems tab to see the actual errors and warnings.
Is it a good practice to use break and continue as sentinel for loops in PHP?
e.g.
if (!empty($var))
break;
do {
if (condition1)
break;
some code;
some code;
if (condition2)
break;
some code;
some code;
if (condition3)
break;
some code;
some code;
} while (false);
vs.
if (!condition1) {
some code;
some code;
if (!condition2) {
some code;
some code;
if (!condition3) {
some code;
some code;
}
}
Some find the first version an abhomination and difficult to read and love the second version. Some find the first version cleaner and easier to read. As the number of conditions multiply, I tend to find the first version easier to follow, as the second one tends to get more and more difficult to follow the level of nesting. Also if the if (condition) break; gets into something only slightly more complex like if (condition) {some code; break}, the do {if .. break; if .. break..;} while(false) pattern gets even more clear compared with equivalend nested ifs.
In light usage it is ok, but in heavy usage it makes your code spaghetti. break and continue is basically just a restricted goto and as such, use sparingly.
It absolutely is, they're both valid programming constructs.
What is not a good idea is the newly introduced GOTO. (Please tell me this was an April fool's joke I didn't see the note about!)
It is perfectly correct to use break or continue as long as it helps to make the code easier to read and understand. I personally use them very rarely, and only when I cannot easily use another structure.
In the case of most while statements, it's easier to achieve the same result as a break or continue by using a boolean variable as the condition for the loop in the first place, and then modifying its value inside the loop.
On the other hand, the best use case for the break, in my opinion, is to save resources if you are iterating through an array or something similar with a for or foreach block and are only interested in processing elements until some item is reached. By using a break after reaching this element, it is possible to save on processing power by breaking out of the loop without going over the remaining elements. This makes the code more efficient without making it less legible.
And of course, it is practically impossible to use switch statements without break.
Another exception is if you need to control nested structures, in which case it is sometimes simpler to use break n or continue n than manipulate multiple variables concurrently. (Even though this use case is probably the most controversial...)
In Python, we use infinite loop and break to improve readability. So yes, you can use it, provided you do it correctly, and for a good reason.
Let me answer with a couple of questions:
Why shouldn't it be considered good practice?
Does it reduce readability of your code?
Does it slow down your for cycles?
For a discussion of break and continue in PHP (and looping in general) have a look at Advanced loops - you get the impression that the author can just about manage to swallow break and continue but not break n and continue n. :-)
In 5+ years programming PHP I never had to use break outside of switch statements.
Continue is sometimes used to skip first or last items in iterations, but I don't like it very much.
Why did they reintroduce GOTO ? that's a shame
To answer the question, in
if (!empty($var))
break;
Why not use return (if in a method context)
if (!empty($var))
return false;
I think this way much clear and makes the caller aware of what's happened inside. A better use for argument errors is using Excecptions, which in facte will break execution a the point they are raised.