Call static method from string in PHP - php

I'm trying to call this from string Yii::app()->user->id_rol. So, I want to take this string and do the call then.
I tried to do this:
$class = "Yii::app()->user->id_rol";
$class = explode('::',$class);
$class[1] = explode('->',$class[1]);
$class2 = new $class[0];
$string = "";
$n = count($class[1]);
for($i = 0; $i<$n;$i++){
(($i+1) == $n) ? $fl = '' : $fl = '->';
$string .= $class[1][$i].$fl;
}
$model = $class2->$string;
...but that doesn't work.
Undefined property: Yii::$app()->user->id_rol
How could I make it work?

I think mnv's comment above is the way to go. Otherwise you risk all sorts of problems with code injection and whatnot. In the worst case, if you really want to do this, I'd recommend doing the following (as much as it pains me to write this):
$code = "return {$VARIABLE_FROM_DB};";
$value = eval($code);
That said, there should be a better way to do what you are trying to do overall. What is the source of the DB provided code? Can you reformat it in a way that you are not saving code into the database?

Related

How do I insert html code into a php regex?

So I am currently in the middle of making a forums software. Something that I wanted for that forums software was a custom template engine. For the most part I have created the template engine, but I am having a small issue with the regex that I use for my IF, ELSEIF, and FOREACH statements.
The issue that I am having is that when I put a chunk of html code in to my regex, nothing will work. Here is an example: https://regex101.com/r/jlawz3/1.
Here is the PHP code that checks for the regex.
$isMatchedAgain = preg_match_all('/{IF:(.*?)}[\s]*?(.*?)[\s]*?{ELSE}[\s]*?(.*?)[\s]*?{ENDIF}/', $this->template, $elseifmatches);
for ($i = 0; $i < count($elseifmatches[0]); $i++) {
$condition = $elseifmatches[1][$i];
$trueval = $elseifmatches[2][$i];
$falseval = (isset($elseifmatches[3][$i])) ? $elseifmatches[3][$i] : false;
$res = eval('return ('.$condition.');');
if ($res===true) {
$this->template = str_replace($elseifmatches[0][$i],$trueval,$this->template);
} else {
$this->template = str_replace($elseifmatches[0][$i],$falseval,$this->template);
}
}
You can do it like this:
function render($content) {
$match = preg_match_all('/{IF:\((.*?)\)}(.*?){ELSE}(.*?)({ENDIF})/s', $content, $matches, PREG_OFFSET_CAPTURE);
if (!$match) {
return $content;
}
$beforeIf = substr($content, 0, $matches[0][0][1]);
$afterIf = substr($content, $matches[4][0][1] + strlen('{ENDIF}'));
$evalCondition = eval('return (' . $matches[1][0][0] . ');');
if ($evalCondition) {
$ifResult = $matches[2][0][0];
} else {
$ifResult = $matches[3][0][0];
}
return
$beforeIf .
$ifResult .
render($afterIf);
}
Working example.
This is a first step. This wont work for example if you have an if within an if.
Talking about mentioned security risk. Since we are using eval (nickname EVIL - for a reason). You should never ever ever process user-input through eval - or use eval at all - there is always a better solution.
For me it looks like you want to give users the ability to write "code" in their posts. If this is the case you can have a look at something like bbcode.
Whatever you do be sure to provide the desired functionality. Taking your example:
!isset($_SESSION['loggedin'])
You could do something like this:
{IS_LOGGED_IN}
Output whatever you want :)
{/IS_LOGGED_IN}
Your renderer would look specificly for this tag and act accordingly.
So after a bit of research, I have figured out that the issue I was facing could be solved by adding /ims to the end of my regex statement. So now my regex statement looks like:
/{IF:(.*?)}[\s]*?(.*?)[\s]*?{ELSE}[\s]*?(.*?)[\s]*?{ENDIF}/ims

How to affect a string to a variable without redefining it

I'm working on a project, and it has a bunch of variables for some links that I define. But I want to add a string at the end of those variable only if I got some GET parameters. The thing is I don't want to have another huge amount of variables and I want to have the same name for the variables. After some research, I came with this operator .= which is perfect for me. I also made a for loop it works well for the variable value, but I don't have the same name.
Here is what I got:
$homeLink = $wURL.'government/'.$job.'/';
$databaseLink = $wURL.'government/'.$job.'/search/database';
$overviewLink = $wURL.'government/'.$job.'/overview';
// Other variables
if (!isset($_SESSION['steamid']) && isset($_GET['uID']) && isset($_GET['uToken'])) {
// redefine the variables like this:
$homeLink .= '?uID='.$userinfoVlife['id'].'&uToken='.$userinfoVlife['websiteMDP'];
/*
OUTPUT: $wURL.'government/'.$job.'/'.'?uID='.$userinfoVlife['id'].'&uToken='.$userinfoVlife['websiteMDP']
*/
// The for loop:
$arr = array($homeLink,$databaseLink,$overviewLink);
$nb = count($arr);
for ($i=0; $i < $nb ; $i++) {
$arr[$i] .= '?uID='.$userinfoVlife['id'].'&uToken='.$userinfoVlife['websiteMDP'];
echo $arr[$i]."<br>";
// have the same output that above but I have to call my variables with $arr[<a number>];
}
}
The thing is I don't want to have another huge amount of variables and I want to have the same name for the variables, any ideas on how I can proceed?
First, your 2 last links are actually both based on the first one, $homeLink:
$homeLink = $wURL.'government/'.$job.'/';
$databaseLink = $homeLink.'search/database';
$overviewLink = $homeLink.'overview';
then why not build the parameter string and then append it?
$homeLink = $wURL.'government/'.$job.'/'
$paramString = '';
if (!isset($_SESSION['steamid']) && isset($_GET['uID']) && isset($_GET['uToken'])) {
$paramString = '?uID='.$userinfoVlife['id'].'&uToken='.$userinfoVlife['websiteMDP'];
}
$databaseLink = $homeLink.'search/database'.$paramString;
$overviewLink = $homeLink.'overview'.$paramString;
$homeLink .= $paramString;
I don't get why you want to store your URLs in an array, these are different URLs, thus to be used in different contexts, having all of them in one array is of course possible but doesn't bring any value, in my opinion.
To conclude, if $userinfoVlife['websiteMDP'] contains a readable password, you definitely have a problem in your application architecture: it's very bad practice to handle raw passwords and it's even worse to pass it in the URL.

Unknown PHP obfuscation technique

I've come accross a piece of code using various techniques of obfuscation and, mostly driven by curiosity, have been trying to understand the techniques it uses.
I've done some work on it, but i'm at a point where I don't understand fully what it's doing :
public $x1528 = null;
public $x153c = null;
function __construct()
{
$this->x1528 = new \StdClass();
$this->x153c = new \StdClass();
$this->x1528->x21a9 = "getSingleton";
$this->x1528->x1569 = "x1565";
$this->x1528->x1e45 = "x1e40";
$this->x153c->x3b3b = "x3b38";
$this->x1528->x16c3 = "x16c2";
$this->x1528->x1bec = "x1be8";
$this->x1528->x245a = "x2455";
$this->x1528->x1b14 = "x10d7";
$this->x153c->x36d4 = "x36d2";
$this->x1528->x24d6 = "getSingleton";
$this->x1528->x1876 = "xf0f";
$this->x1528->x2901 = "x2900";
$this->x1528->x1877 = "x1876";
$this->x153c->x335b = "x3356";
$this->x1528->x2836 = "x2833";
$this->x1528->x2119 = "x2115";
$this->x1528->x18bb = "xf3d";
$this->x153c->x349e = "x349a";
$this->x1528->x2383 = "getData";
$this->x1528->x17b1 = "x5f2";
$this->x153c->x2d06 = "xf41";
$this->x1528->x1f35 = "x1f30";
$this->x1528->x1a93 = "x1138";
$this->x1528->x1d79 = "x1d76";
$this->x1528->x1d7c = "x1d79";
$this->x153c->x3248 = "_isAllowed";
...
[it keeps going for a while...]
So it declares empty variables, generates empty objects, and then stores strings and references to other variables, but...
for example,
$this->x1528->x21a9 = "getSingleton";
What is x21a9 ? There's no reference to this anywhere, and I thought the x1528 variable was empty ? Also, is this a way of referencing the $x1528 without the $, because i've never seen this syntax before.
This is using PHP techniques I was not aware of, and this has made me very curious. Any help ?
Without seeing the entire code it's hard to tell. But basically this is just "gibberish" making it hard to read, but basic PHP nevertheless.
What is x21a9 ?
It's just a random property set on the $x1528 class. Like:
$dummyClass = new StdClass(); // Same as $this->x1528 = new \StdClass();
$dummyClass->foo = "bar"; // Same as $this->x1528->x21a9 = "getSingleton";
Now, echo $dummyClass->foo would return bar. It's just setting a property with a value, but with "cryptic" names.
I thought the x1528 variable was empty ?
It starts out empty at the beginning of the class, but then in the constructor, it's immediately set up as an instance of StdClass:
$this->x1528 = new \StdClass();
Also, is this a way of referencing the $x1528 without the $, because i've never seen this syntax before.
This is basic syntax for objects. The object itself has a $ in front of it, but the properties don't.

Cut some word from php available?

Cut some word from php available ?
First access to page for example
www.mysite.com/test.php?ABD_07,_oU_876.00/8999&message=success
From my php code, i will get $curreny_link_redirect = test.php?ABD_07,_oU_876.00/8999&message=success
And i want to get $curreny_link_redirect_new = test.php?ABD_07,_oU_876.00/8999
( Cut &message=success )
How can i do ?
<?PHP
$current_link = "$_SERVER[REQUEST_URI]";
$curreny_link_redirect = substr($current_link,1);
$curreny_link_redirect_new = str_replace('', '&message=success', $curreny_link_redirect);
echo $curreny_link_redirect_new;
?>
Your str_replace call is inverse of what it should be. What you want to replace should be the first parameter, not the second.
//Wrong
$curreny_link_redirect_new = str_replace('', '&message=success', $curreny_link_redirect);
//Right
$curreny_link_redirect_new = str_replace('&message=success','', $curreny_link_redirect);
While simple way to do this is to use regex (or even static with str_replace()), I recommend to use built-in functions for url handling. This may be useful when working with complex parameters or multiple parameters:
$data = 'www.mysite.com/test.php?ABD_07,_oU_876.00/8999&message=success';
$url = parse_url($data);
parse_str($url['query'], $url['query']);
//now, do something with parameters:
unset($url['query']['message']);
$url['query'] = http_build_query($url['query']);
$url = http_build_url($url);
-please, note, that http_build_url() is a PECL function (pecl_http to be precise). The way above may look more complex, but it has benefits - first, as I've already mentioned, this will be easy to modify for working with complex parameters or multiple parameters. Second, it will produce valid url - i.e. encode such things as slashes, spaces, e t.c. - in result. Thus, result will always be correct url.
Do like this
<?php
$str = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
echo $str = array_shift(explode('&',$str));
Try this:
$current_link_path = substr($_SERVER['PHP_SELF'], 1);
$params = $_GET;
if ($params['message'] == 'success') {
unset($params['message']);
}
$current_link_redirect = $current_link_path . '?' . http_build_query($params);
Maybe not an answer, but a disclaimer for future visitors:
1) I would strongly recommend the function: http://pl1.php.net/parse_url.
And in that case:
$current_link = "$_SERVER[REQUEST_URI]";
$arguments = explode('&', parse_url($current_link, PHP_URL_QUERY));
print_r($arguments);
2) To build new url, use http://pl1.php.net/manual/en/function.http-build-url.php. This is the best, future modifications ready solution I think.
In that case this solution is a little overkill, but these functions are really great, and worth to introduce here.
Best regards

Get text file using function in PHP

Suppose that I have the PHP function as below:
function.php
<?php
function getDataInFile($PMTA_FILE){
$PMTA_DATE = date("Y-m-d");
$lineFromText = explode("\n", $PMTA_FILE);
$number_bar_charts = 13;
$row = 0;
$cate = "";
$total ="";
$fail = "";
$mailSuc = "";
$title = "";
foreach($lineFromText as $line){
if($row < $number_bar_charts){
$words = explode(";",$line);
$dateTime .= ','.$words[0];
if($title == ""){
$title = $words[0];
}
$cate .= ','."'$words[5]'";
$total .= ','.$words[6];
$fail .= ','.$words[7];
$mailSuc .= ','.((int)$words[6] - (int)$words[7]);
$row++;
}
}
}
?>
This is code below that I call the function to use in getFile.php.
<?php
include("include/function.php");
$PMTA_DATE = date("Y-m-d");
getDataInFile("../stats_domain_recepteur.affinitead.net.".$PMTA_DATE.".txt");
?>
In fact, it can not read data from the file, I got the error messages Undefined variable: dateTime in C:\wamp\www\chat\include\function.php on line 15,Notice: Undefined offset: 5 in C:\wamp\www\chat\include\function.php on line 19....
I do not know how to fix this, Anyone help me please, Thanks.
These are Notices only. They are not terrible errors that will blow up your code, but some code reviewers would make you fix them. PHP is just giving you a polite nudge, but will work anyhow. Fatal errors are the big, bad problems that will stop PHP in its tracks.
Here are the problems PHP found...
You're appending data to the string $dateTime on each iteration. On the first pass through the variable doesn't yet exist. PHP doesn't really care, but will issue a warning. To get rid of that problem, define $dateTime before you use it.
$dateTime = null;
The second problem is an array out of bounds exception. You are trying to do something with $words[5] when that array index doesn't exist. In general, you should check that array indexes, variables and other fun stuff actually exist before you try to use them.
$cate .= sprintf(",'%s'", isset($word[5]) ? $word[5] : '');
If you don't want to see Notices and Warnings reported in the error log, see PHP Error Handling to learn how to set which error levels you want to see in your log.
You should also read all about the file_get_contents function to actually get the file in the first place!
add $dateTime = ''; before foreach($lineFromText as $line){
this will works fine.
The error messages are 100% legit: you're trying to use a variable which hasn't been initialized before. Put this code above the loop and you'll get rid of this error:
$dateTime = '';
Regarding the second error - it tells that you don't have 6-th element in the array, so you'd better replace that code with a check:
$cate .= sprintf(",'%s'", isset($word[5]) ? $word[5] : '');
Extrapolate this check to other index accesses, as well.

Categories