hello am still learning php and trying to call php function by url link and i did found this code
if(function_exists($_GET['f'])) {
$_GET['f']();
}
but it's not safe for my function so i did something like that
if($_GET['f']=='mouner'){
function mouner(){
$s = 'my name is mouner';
return($s);
}
echo mouner();
}
is that safe code ? and if it's not what is the best way to call function by url with no security risk
As #JuliePelletier suggested, you need to check your user input before executing any functions associated to it. Another handy way might be something like this:
$funcs["foo"] = function()
{
echo "In foo function";
};
$funcs["bar"] = function()
{
echo "In bar function";
};
if (isset($funcs[$_GET["f"]]))
$funcs[$_GET["f"]]();
Store the functions (either anonymous or just by their name) in an associative array of allowed functions and just execute those.
You are right that the first option is extremely risky, which is why you need to validate user inputs (including GET parameters).
Your second option does exactly that. The code is not perfect but does solve that serious vulnerability.
Julie has the right answer, just offering up some code cleanup:
if($_GET['f'] == 'mouner'){
$s = 'my name is mouner';
echo $s;
}
If you expect the result to have a lot of variation, could make use of switch() like so:
if(isset($_GET['f'])){
$s = "My name is ";
switch($_GET['f']){
case 'mouner':
$s .= "Mouner";
break;
}
echo $s;
}
Related
In Drupal, there are many functions that are hook_functionname1, hook_functionname2. When writing a module, you have to replace the text 'hook' with your module name, so Drupal loads your module "my_drupal_module" and runs hooks like "my_drupal_module_functionname1" and "my_drupal_module_functionname2".
Is it possible in PHP to use DEFINE to simply define the word "hook" and set it to a string? If it is possible, then you should be able to copy and paste word-for-word hook_anything and not have to change it. And, if you ever wanted to change the name of your module, you would merely change the single constant, rather than find/replace all the function names.
So can you use DEFINE or some other setting to meta-program in PHP?
You want something like:
$moduleFunctionName = 'hook';
$functionNameOne = $moduleFunctionName . '_functionname1';
$functionNameTwo = $moduleFunctionName . '_functionname2';
$functionNameOne = function($var) {
// blah
}
..//
Function $functionNameOne is defined through anonymous function. It becames available in php from php 5.3.0
Maybe you want something like this
<?
define('PREFIX', 'myprefix');
//like this time you deside that this will me the second part
$somevar = '_this_function_name';
// now we combine prefix and name
$function_name = PREFIX . $somevar;
// now we check if we can run this function
if(!function_exists($function_name)){
echo "no function $funcion_name exist";
}
else{
$function_name();
}
function myprefix_this_function_name(){
echo 'running function';
}
?>
this will output
running function
This actually works:
define('FN_NAMESPACE', 'hook_');
${FN_NAMESPACE . 'functionNameOne'} = function($var) {
echo "Hi, I got $var\n";
};
$hook_functionNameOne('test');
Will output
Hi, I got test
There are two columns in the database table "system". I have the systemId and want to get the mobileSystemId. But the variable $mobileSystemIds which I already defined as global is always empty.
EDIT: Now array_map doesn´t work. I always get my Exception output "Arrayfehler ArrayMap"
I have the following code :
$mobileSystemIds=array();
function getMobileSystemId($systemId)
{
global $mysqli;
global $mobileSystemIds;
$query="SELECT mobileSystemId FROM system WHERE systemId ='" .$systemId ."'";
if(!$result=$mysqli->query($query))
{
echo "Datenbankfehler DB-QUery";
exit(0);
}
if (!$mobileSystemId=$result->fetch_assoc())
{
echo "Datenbankfehler DB-Fetch";
exit(0);
}
$mobileSystemId=$mobileSystemId["mobileSystemId"];
echo "mobile System ID: " .$mobileSystemId ."<br />";
return $mobileSystemId;
}
if(!$mobileSystemIds=array_map("getMobileSystemId",$systemList))
{
echo "Arrayfehler ArrayMap";
}
In this case, using a return in your function would be much cleaner.
Nothing to do with your problem, but is your $systemId var trusted ? (To prevent SQL injection).
Update:
if(!$mobileSystemIds=array_map("getMobileSystemId",$systemList))
{
echo "Arrayfehler ArrayMap";
}
ought to read (just checked; it works for me):
$mobileSystemIds = array_map('getMobileSystemId', $systemsList);
if (empty($mobileSystemIds))
{
if (empty($systemsList) || !(is_array($systemsList)))
echo "OK: no mobile IDs, but no systems either";
else
echo "THIS now is strange :-(";
}
else
{
echo "Alles OK";
var_dump($mobileSystemIds);
}
I tried this by returning a dummy value based on input; if it does not work for you, there must be something strange in the database.
(Update: the text below refers to your original code, which did not use array mapping)
Your code ought to be working as it is. You put several $mobileSystemId 's into a single $mobileSystemId.
It works: I tested with a simpler code, removing the DB calls but leaving your code, and spelling, untouched.
So, the error must be elsewhere. I would guess that this code is included into something else, and:
the $mobileSystemIds = array(); declaration gets executed more than once, thereby losing all its data;
the $mobileSystemIds = array(); declaration is itself included in a more local scope and you read it from outside, reading an empty value or a totally different value.
Try replacing the first part of your code with:
GLOBAL $mobileSystemsIds;
if (defined($mobileSystemsIds))
trigger_error("mobileSystemsId defined more than once", E_USER_ERROR);
else
$mobileSystemsIds = array();
and also, in the function body:
if (!defined($mobileSystemsId))
trigger_error("mobileSystemsId should have been defined", E_USER_ERROR);
another simple thing that's got me stuck:
I'm using the following to check on the current url and select a div class dependent on the result:
$checkit = $_SERVER['PHP_SELF'];
...
<li "; if(strstr($checkit,'welcome')) { echo "class='active_tab'"; }...
What I want to be able to do is also check if the url includes other words which would also require that same 'li' item to be given the 'active_tab' class, but i can't figure out the format. Something like this, although obviously this doesn't work:
<li "; if(strstr($checkit,'welcome', 'home', 'yourprofile')) { echo "class='active_tab'"; }...
Can someone help?
I know there's a better way but stop-gap fix would be:
$searchStrings = array('welcome','home','yourprofile');
$stringFound = false;
foreach($searchStrings as $checkString)
{
if(strstr($checkit, $checkString))
{
$stringFound = true;
break;
}
}
Then use $stringFound to change your output.
Edit 1: Switched continuefor break thanks ZombieHunter (It's late -_-)
Edit 2: Alternatively you can use a regular expression (though I think that's overkill here)
if(preg_match('/(welcome|home|your profile)/',$checkit))
{
// Do your stuff here
}
But this is not as expressive (easier to read and extend an array) and if those values start piling up its easier to hook the array into some storage like DB query.
I am trying to grasp the concept of PHP functions. I know how to create one.
function functionName()
{
//code to be executed;
}
I also know how to call a function. I am just a little confused as to what a parameter is for. I have read the php manual and w3schools.com's tutorial. From my understanding, you need a parameter to pass a value to the function? If that is correct why not just create it within the function? Why use a parameter?
Like this:
<?php
function num()
{
$s=14;
echo $s;
}
num();
?>
I know you can do:
<?php
function num($s=14)
{
echo $s;
}
num();
?>
or:
<?php
function num($s)
{
echo $s;
}
num($s=14);
?>
Could someone give me a real application of using a parameter, for say maybe a user based dynamic content website? I think it would help me understand it better.
Passing a parameter allows you to use one function numerous times. For example:
If you wanted to write ONE function that sent mail - you could pass the following parameters:
$to = $_POST['to'];
$from = $_POST['from'];
$subject = $_POST['subject'];
Then, in your function:
function sendmail($to, $from, $subject){
//code to be executed
}
Now you can reuse your send function at various points in your web app.
Here is an example, say you have numbers representing colors (this is common in storing data in a database) and you want to output what number represent's what color.
Say you had to do this a hundrend times for a hundred numbers.
You'd get pretty tired writing 100 if statments 100 times.
Here is a function example...
function colorType($type) {
if ($type == 1) {
return "Green";
}
elseif ($type == 2) {
return "Blue";
}
elseif ($type == 3) {
return "Red";
}
// etc
}
echo colorType(1) . "<br>"; // Green
echo colorType(2) . "<br>"; // Blue
echo colorType(3) . "<br>"; // Red
A function does something, and gives a result. It may accept parameters to arrive at that result, it may not. The simple calculator, as aforementioned, is a good one.
The easiest way to understand functions and parameters is to just read the PHP manual—most of the functions in the core PHP language take parameters of some sort. These functions are no different to the functions you write.
Let's assume you want to create a function that will allow people to sum numbers, you can't write needed variables in functions because you want others to input it and your function shows output:
function add($num1, $num2){
return $num1 + $num2;
}
Now anyone can call/use your function to sum numbers:
echo add(5,1); // 6
echo add(2,1); // 3
echo add(15,1); // 16
That's the most simplest example one can give to explain why you need parameters :)
When you specify function name($var=VALUE), you are setting a default.
function doit($s=14) {
return $s + 5;
}
doit(); // returns 19
doit(3); // returns 8
it makes your functions flexible to be reused in various situations, otherwise you would have to write many functions, one for each scenario. this is not only tedious, but becomes a nightmare if you have to fix something in those functions. instead of fixing it in one place, you would have to fix it in many places. you basically never want to have to copy paste code you have already written, instead you use arguments to make one set of the code flexible enough to handle each situation.
Paramaters allow your function to see the value of variables that exist outside of itself.
For example:
function F_to_C($temp) {
$temp = ($temp - 32) / 1.8;
return $temp;
}
$temperature = 32;
$new_temperature = F_to_C($temperature); // 0
echo $temperature;
$temperature2 = F_to_C(212); // 100
echo $temperature2;
Here we take $temperature, which we define in the code, but could be user input as from a form, and then send it to the function F_to_C. This allows us to convert it to Celsius, so we can then display it thereafter. In the next section, we then re-use the function to convert the boiling point, which is sent directly this time as the value 212. If we had embedded $temperature = 32 in the function the first time, then we would still get 0 as a result. However since we're using parameters, we instead get 100 back, because it's processing the value we specified when we invoked the function.
I'm writing a unit testing platform and I want to be able to dynamically generate a function based off of each function in the web service I am testing. The dynamic function would be generated with default(correct) values for each argument in the web service and allow them to be easily traded out with incorrect values for error testing.
$arrayOfDefVals = array(123, 'foo');
testFunctionGenerator('function1', $arrayOfDefVals);
//resulting php code:
function1Test($expectedOutput, $arg1=123, $arg2='foo')
{
try
{
$out = function1($arg1, $arg2);
if($expectedOutput === $out)
return true;
else
return $out;
}
catch ($e)
{
return $e;
}
}
This would allow me to quickly and cleanly pass one bad argument, or any number of bad arguments, at a time to test all of the error catching in the web service.
My main question is:
Is this even possible with php?
If it's not possible, is there an alternative?
EDIT: I'm not looking for a unit test, I'm trying to learn by doing. I'm not looking for advice on this code example, it's just a quick example of what I would like to do. I just want to know if it's possible.
I would not try that first as PHP has not build-in macro support. But probably something in that direction:
function function1($param1, $param2)
{
return sprintf("param1: %d, param2: '%s'\n", $param1, $param2);
}
/* Macro: basically a port of your macro as a function */
$testFunctionGenerator = function($callback, array $defVals = array())
{
$defVals = array_values($defVals); // list, not hash
return function() use ($callback, $defVals)
{
$callArgs = func_get_args();
$expectedOutput = array_shift($callArgs);
$callArgs += $defVals;
return $expectedOutput == call_user_func_array($callback, $callArgs);
};
};
/* Use */
$arrayOfDefVals = array(123, 'foo');
$function1Test = $testFunctionGenerator('function1', $arrayOfDefVals);
var_dump($function1Test("param1: 456, param2: 'foo'\n", 456)); # bool(true)
Probably this is helpful, see Anonymous functionsDocs, func_get_argsDocs, the Union array operatorDocs and call_user_func_arrayDocs.
Well, for starters, you can set default parameters in functions:
function function1Test($expectedOutput, $testArg1=123, $testArg2='foo') {
...
}
Beyond that, I'm not really sure what you're trying to achieve with this "function generator"...
Read about call_user_func and func_get_args
This example from the manual should get you on the right track:
<?php
call_user_func(function($arg) { print "[$arg]\n"; }, 'test'); /* As of PHP 5.3.0 */
?>
If it's a function you have file access to (i.e., it's not a part of the PHP standard library and you have permissions to read from the file), you could do something like this:
Assume we have a function like this located in some file. The file will have to be included (i.e., the function will have to be in PHP's internal symbol table):
function my_original_function($param1, $param2)
{
echo "$param1 $param2 \n";
}
Use the ReflectionFunction class to get details about that function and where it's defined: http://us2.php.net/manual/en/class.reflectionfunction.php.
$reflection = new ReflectionFunction('my_original_function');
Next, you can use the reflection instance to get the path to that file, the first/last line number of the function, and the parameters to the function:
$file_path = $reflection->getFileName();
$start_line = $reflection->getStartLine();
$end_line = $reflection->getEndLine();
$params = $reflection->getParameters();
Using these, you could:
read the function out of the file into a string
rewrite the first line to change the function name, using the known function name as a reference
rewrite the first line to alter the parameter defaults, using $params as a reference
write the altered function string to a file
include the file
Voila! You now have the new function available.
Depending on what it is you're actually trying to accomplish, you could also potentially just use ReflectionFunction::getClosure() to get an closure copy of the function, assign it to whatever variable you want, and define the parameters there. See: http://us.php.net/manual/en/functions.anonymous.php. Or you could instantiate multiple ReflectionFunctions and call ReflectionFunction::invoke()/invokeArgs() with the parameter set you want. See: http://us2.php.net/manual/en/reflectionfunction.invokeargs.php or http://us2.php.net/manual/en/reflectionfunction.invoke.php