PHP: How to shorten that code? - php

I know how to code a solution to my problem, I am just interested in the shortest way to code it. Thats the problem:
I am parsing a URL, the parsing can have 3 results, local, staging or production. I figure out which one it is using a regex. I do that in a function called getServer().
Now in that function I return an array which has 3 elements which are either 0 or 1. If the first is 1 and the other two are 0, it means, its a local server for example.
Now when I get that array back I still have to write an if to see which of the array elems is 1.
if($returnArrayFromFunction[0] == '1') {
// do the stuff for the local server case
}
if($returnArrayFromFunction[1] == '1') {
// do the stuff for the staging server case
}
if($returnArrayFromFunction[2] == '1') {
// do the stuff for the production server case
}
Is there some way to shorten that code?
Thanks for your time!

Don't return an array with the index of the value 1 encoding the result. Define three constants
define('SERVER_LOCAL', 1);
define('SERVER_STAGING', 2);
define('SERVER_PRODUCTION', 4);
And return the correct constant from your code, then use a switch statement
switch($serverType) {
case(SERVER_LOCAL)::
DoStuffForLocalServer();
break;
case ...
If terseness is your goal, shorten the switch to
$serverType == SERVER_LOCAL ? doLocal() : $serverType == SERVER_STAGING ? doStaging() : doProduction();
Is as short as it gets, but will probanly be frowned upon :-)

Why not just return an id number in getServer()?
$serverId = getServer();
switch ($serverId) {
case 0: // Local
// Code
break;
case 1: // Staging
// Code
break;
case 2: // Production
// Code
}
Note:
If you will need to use these server ids elsewhere in the code, it may be easier to keep track of which id corresponds to which server by using a naming convention with define(). This can also make your code easier to read and thus easier to debug.
define('SERVER_LOCAL', 0);
define('SERVER_STAGING', 1);
define('SERVER_PRODUCTION', 2);
Then you can replace the above switch with the following:
switch ($serverId) {
case SERVER_LOCAL:
// Code
break;
case SERVER_STAGING:
// Code
break;
case SERVER_PRODUCTION:
// Code
}

Try this code
$case=array_search(1,$returnArrayFromFunction);
switch($case)
{
0:
break;
// do the stuff for the local server case
1:
break;
// do the stuff for the staging server case
2:
// do the stuff for the production server case
break;
}

Try like
foreach($returnArrayFromFunction as $key=>$return)
{
if($return == '1')
{
switch($key)
{
case '0' : //Stuff at local
break;
case '1' : //Stuff at Staging
break;
case '2' : //Stuff at production
break;
}
}
}

$code = join('', $returnArrayFromFunction );
//something like '111' / '010' / '110'
switch( $code ){
case '111':
//all values 1
break;
case '001':
//something else
break;
}

Your getServer() function should just return one value instead of array. And then use following code:
$serverId = getServer();
switch ($serverId) {
case 0: // local server
// Your code
break;
case 1: // testing server
// Your code
break;
case 2: // live server
// Your code
}

Related

PHP file_get_contents check source online or not before do the execution

I'm using PHP file_get_contents to read text file data.
Assuming I have 2 IP Address, 1 online and 1 offline:
192.168.180.181 - Online
192.168.180.182 - Offline
And the PHP
$fileAccept = file_get_contents("\\\\192.168.180.181\\Reports\\".$dModel['MODEL_NAME'].$source."\\Accept\\Accept_".$dDtl['MODEL_CODE']."_".$dateCode."_".$dDtl['TS_CODE'].".txt");
As We Know IP Address 192.168.180.182 is offline, then I tried to run the code. And result the page always loading.
My question, how can I prevent it maybe first need to check the IP is alive or not, if alive then can continue to next step.
Maybe something like this:
if(IP IS OFFLINE)
{
echo "do not do anything";
}
else
{
echo "do something";
}
you can try something like that
$scc = stream_context_create(array('http'=>
array(
'timeout' => 120, //120 seconds
)
));
$url = "http://192.168.180.181/....";
$handle = file_get_contents('$url, false, $scc);
you can create two handles and check whether is ok with if statement, of course you can change the timeout to suites you
Update:
if accessing file locally you can check this stream_set_timeout() function , the documentation is here
This solution is based on pinging the IP you need to check
class IPChecker{
public static function isIPOnline($ip){
switch (SELF::currentOS()){
case "windows":
$arg = "n";
break;
case "linux":
$arg = "c";
break;
default: throw new \Exception('unknown OS');
}
$result = "";
$output = [];
// to debug errors add 2>&1 to the command to fill $output
// https://stackoverflow.com/questions/16665041/php-why-isnt-exec-returning-output
exec("ping -$arg 2 $ip " , $output, $result);
// if 0 then the there is no errors like "Destination Host Unreachable"
if ($result === 0) return true;
return false;
}
public static function currentOS(){
if(strpos(strtolower(PHP_OS), "win") !== false) return 'windows';
elseif (strpos(strtolower(PHP_OS), "linux") !== false) return 'linux';
//TODO: extend other OSs here
else return 'unknown';
}
}
usage example
var_dump( IPChecker::isIPOnline("192.168.180.181") );// should outputs bool(true)
var_dump( IPChecker::isIPOnline("192.168.180.182") );// should outputs bool(false)
I have used these answers (1, 2) in my answer

PHP eval code sandbox break

I noticed a heavily downvoted comment in here: http://php.net/manual/en/function.php-check-syntax.php
function eval_syntax($code)
{
$braces = 0;
$inString = 0;
// We need to know if braces are correctly balanced.
// This is not trivial due to variable interpolation
// which occurs in heredoc, backticked and double quoted strings
foreach (token_get_all('<?php ' . $code) as $token)
{
if (is_array($token))
{
switch ($token[0])
{
case T_CURLY_OPEN:
case T_DOLLAR_OPEN_CURLY_BRACES:
case T_START_HEREDOC: ++$inString; break;
case T_END_HEREDOC: --$inString; break;
}
}
else if ($inString & 1)
{
switch ($token)
{
case '`':
case '"': --$inString; break;
}
}
else
{
switch ($token)
{
case '`':
case '"': ++$inString; break;
case '{': ++$braces; break;
case '}':
if ($inString) --$inString;
else
{
--$braces;
if ($braces < 0) return false;
}
break;
}
}
}
// If $braces is not zero, then we are sure that $code is broken.
// We run it anyway in order to catch the error message and line number.
// Else, if $braces are correctly balanced, then we can safely put
// $code in a dead code sandbox to prevent its execution.
// Note that without this sandbox, a function or class declaration inside
// $code could throw a "Cannot redeclare" fatal error.
echo "Braces: ".$braces."\r\n";
$braces || $code = "if(0){{$code}\n}";
if (false === eval($code)) {}
}
eval_syntax("file_put_contents('/home/yourname/Desktop/done.txt', 'OVERWRITTEN');");
I tried to bypass the code to maliciously execute user-input, but I couldn't. I wonder why it got downvoted.
As you can see if curly brackets are not matching, it doesn't add the 'if(0){' . $code . '} and executes the user input with mismatching curly brackets which will throw exception and won't really run.
If curly brackets are a match, it calls the eval, but its inside a if {0} "sandbox". How can someone bypass this?
I know eval is insecure, but I want to know what's the trick here. How can you bypass security of if (0) and braces check in the code above?
You can try directly the code from php.net or my minified/edited version above. Point is proving that this code is not secure and user an execute arbitrary PHP Code

How to get user input for switch statement in php?

As questioned above I'm trying to get user input in my PHP script to do further tasks. Is there any method in PHP to get user input like 'scanf()' used in C
<?php
echo "Swapping Numbers </br> Please select the method: </br>";
echo "1. Using 3rd variable </br> 2. Using add/sub </br> 3. Using mul/div";
//read user input $choice
switch($choice)
{
case 1:
break;
case 2:
break;
case 3:
break;
default:
echo "</br>You entered wrong choice";
}
?>
the STDIN constant is pre-defined and available for you to use immediately.
You can get user input using fgets and fscanf
<?php
$line = trim(fgets(STDIN)); // reads one line from STDIN
fscanf(STDIN, "%d\n", $number); // reads number from STDIN
For example
<?php
echo "Enter a number: ";
fscanf(STDIN, "%d\n", $number);
switch ($number) {
case 1: echo "one\n"; break;
case 2: echo "two\n"; break;
case 3: echo "three\n"; break;
default: echo "I can't count that high\n";
}
Check out the I/O docs for more detailed information
You should use readline() :
var_dump(readline('Enter number: '));
You can handle user input from form element or from url.
in your case you can use like this.
$choice = $_GET['choise'];
User will type like this
http://localhost/your_file_name.php?choise=option
than you should use your switch
switch($choice)
{
case 1:
break;
case 2:
break;
case 3:
break;
default:
echo "</br>You entered wrong choice";
}
?>

Php error Working with get varialbes

i have a php code and when i add some gets variables i get error, 500, i tested it with ajax and without ajax(directly writing the url on the adress bar)
When i go with localhost/ajax/test.php?did=1 everything is fine but when i go with localhost/ajax/test.php?did=1&task=1 the problem happens
all the functions are created before on the ../php/core.php
Here is the code
<?php
require '../php/core.php';
$did = floor($_GET['did']);
if (device_exist($did) && amlogedin() && intouch_get($uid, $did) == 2) {
$task = floor($_GET['task']);
$id = safestring($_GET['id']);
switch ($task) {
case 1:
if (feature_removefeature($did, $fid)) {
echo donemsg("Feature Removed");
}
break;
}
design_makefeturelist($did);
}
else {
echo 'Sorry, some thing is wrong';
}
Almost sure that you've got an error in the feature_removefeature or donemsg function. Because after you set task=1 it will enter the case 1: statement. You could replace the if with a simple echo "lala"; to check it out.
ps. Is $fid already set?

Php connection_status

I write a script for a alerter service. I used php connection_status function to get connection status. Because the script require a inf loop. I look some example and try other scripts but connection_status function always return 0. I think i tried all the script ways. Please help me.
<?php
ignore_user_abort (TRUE);
$x=0;
while ($x++ < 20) {
print $x;
sleep (1);
}
switch (connection_status ()) {
case CONNECTION_NORMAL:
$status = 'Normal';
break;
case CONNECTION_ABORTED:
$status = 'User Abort';
break;
case CONNECTION_TIMEOUT:
$status = 'Max Execution Time exceeded';
break;
case (CONNECTION_ABORTED & CONNECTION_TIMEOUT):
$status = 'Aborted and Timed Out';
break;
default:
$status = 'Unknown';
break;
}
file_put_contents('test.txt',$status);
?>
My system;
php-5.3.1-1 and apache-2.2.14-1
this works... I tested to my space, works if user close windows, but if user press esc button don't work, I really don't know why...
<?php
ignore_user_abort (TRUE);
$x=0;
while (1) {
echo "\n";
if (connection_status()!=0){
file_put_contents('test.txt',connection_status());
die();
}
}
file_put_contents('test.txt',connection_status());
?>
The function connection_status return a int value...
try to add ob_implicit_flush(); in the head
Thanks for all answers! I find a way to solve problem. May be output buffer is the reason for this problem. I run flush(),ob_flush() functions after output and solve the problem! Again thanks alot.
<?php
ignore_user_abort (TRUE);
$x=0;
while ($x++ < 10) {
print " ";
flush();
ob_flush();
sleep (1);
}
switch (connection_status ()) {
case CONNECTION_NORMAL:
$status = 'Normal';
break;
case CONNECTION_ABORTED:
$status = 'User Abort';
break;
case CONNECTION_TIMEOUT:
$status = 'Max Execution Time exceeded';
break;
case (CONNECTION_ABORTED & CONNECTION_TIMEOUT):
$status = 'Aborted and Timed Out';
break;
default:
$status = 'Unknown';
break;
}
file_put_contents('testa.txt',$status);
?>
Nothing of the above worked for me, so I wrote this:
https://bitbucket.org/sivann/coolagent/raw/7d024bfff4a7ef3ce90dff14d4953b3347dfeaa2/server/app/src/Netstat.php which actually detects connection status from OS. Linux only.

Categories