[英]How to get the value of if condition that make the condition TRUE
我正在嘗試獲取使條件為 TRUE 的 if 條件的值,我有以下示例:
(代碼.php)
<?php
$a = 'USERNAME';
$b = 'LASTNAME';
if(substr($a, 0, strlen("<SCRIPT"))=== "<SCRIPT Abdalla $a " ) {
}
?>
在上面的例子中,我試圖在沒有雙引號的情況下獲得<SCRIPT
值。 我嘗試了一些步驟,但它仍然得到帶有值的雙引號( <SCRIPT
)。 然后我計划將值<SCRIPT
分配給另一個變量。 下一個代碼顯示了我的代碼以獲取結果,但它仍然無法正常工作:
(測試.php)
<?php
$file='';
$handle = fopen('code.php','r+');
if ($handle) {
while (($buffer=fgets($handle, 4096)) !== false) {
$file.=$buffer."\n";
}
if (!feof($handle)) {
die('error');
}
fclose($handle);
}
//take note of the use of single quotes to wrap this regex, as we do not want PHP parser to eval the $ in the regex string
preg_match_all('/\s*?(\$[\S]+?)\s*?\=(\"?[\S]+?\"?);/',$file,$matches, PREG_SET_ORDER);
$varval=array();
foreach($matches as $match){
$tmp=$match[2];
if(substr($tmp,0,1)=='"' && substr($tmp,-1,1)=='"'){
//evaluate variables in string. we can evaluate with the current object as the variable should be declared first as of proper PHP syntax
$tmp=substr($tmp, 1,-1); //remove quotes
$tmp=replaceFromObject($tmp, $varval);
}
$varval[$match[1]]=$tmp; //we do not need to check if exists, because we should replace with the latest value.
}
/*
The below stores all quoted text and replace them with our own special variable %var0%, %var1%, %var2%.... %varN%.
This is because there could be cases like if("test == 3" == $a) or even worse if("if(test=3)" == $a), which will make regex/parsing tricky if we do not substitute these quoted text out just like a parser/compiler would.
Note: Something I didn't do. We should really first scan the whole text using preg_match to find if there are any text using this format of variables as well, to prevent collisions!
If there are, we can set a loop to check and append some character to our own special variable like %varrN%, %varrrN%, %varrrrN%...
until we find no collisions and it is safe to use. I will leave this simple regex exercise for you to do on your own. Create the regex to find the file for %varN%...
*/
preg_match_all("/\"([\s\S]*?)\"/", $file, $matches, PREG_SET_ORDER);
$stringvars=array();
$key="%var";
$count=0;
foreach($matches as $match){
if(!in_array($match[1], $stringvars)){
$stringvars[$key.$count.'%']=$match[1];
$file=preg_replace("/\"".preg_quote($match[1])."\"/", $key.$count.'%', $file); //take note of the change to preg_quote
$count++;
}
}
// now we parse the whole text for if(subject anycomparator value)
preg_match_all("/if\s*?\(([\s\S]*?)([\=|\>|\<][\=]{0,2})\s*?([\S\s]*?)\s*?\)/", $file, $matches,PREG_SET_ORDER);
$conditionals=array();
foreach($matches as $match){
$conditionals[]=array(
'subject'=>replaceFromObject(replaceFromObject(trim($match[1]),$stringvars),$varval),
//the order does matter, we replace the string first, then the variables, as there might be variables in the double quoted strings which we should evaluate
'comparator'=>$match[2],
'value'=>replaceFromObject(replaceFromObject(trim($match[3]),$stringvars),$varval),
);
}
foreach ($conditionals as $c){
// echo htmlspecialchars($c['subject']).' ';
// echo htmlspecialchars($c['comparator']).' ';
echo htmlspecialchars($c['value']);
echo "<br/>";
}
/* now this function can be used to replace both the quoted strings AND the variables */
function replaceFromObject($s, $obj){
foreach($obj as $key=>$value){
$s=preg_replace('/'.preg_quote($key).'/', $value, $s); //take note of the preg_quote as the string may contain regex keywords
}
return $s;
}
?>
我想要一種打印使 if 條件為 TRUE 的值的方法,即 (
<SCRIPT
您的目標似乎奇怪地具體,但這里有一個解決您的問題的方法。
file_get_contents
來讀取 php 文件的實際源代碼。 您將獲得生成的 html 等價物。 如果您正在獲取源代碼,則意味着您已將allow_url_fopen
設置為true
。 這會使您的 Web 應用程序面臨潛在的極具破壞性的腳本注入可能性,除非您知道自己在做什么並且小心並與您的代碼保持一致。 您應該嘗試使用fgets
代替。 此代碼基本上與您的file_get_contents
相同。$file='';
$handle = fopen('code.php','r+');
if ($handle) {
while (($buffer=fgets($handle, 4096)) !== false) {
$file.=$buffer."\n";
}
if (!feof($handle)) {
die('error');
}
fclose($handle);
}
if(strpos($value, 'if') != false)
會將位置 0 呈現為 false,在您的情況下應該是 true,就if
在位置 0。比較器應該是嚴格的if(strpos($value, 'if') !== false)
。$pos1 = strpos($value, '==') + 2
指向第一個=
之后的 2 個字符,這在技術上是您的===
最后一個=
。 事實上,使用您當前的代碼,您將得到= "<SCRIPT"
作為結果。現在的解決方案
為了僅針對您的情況解決它,您只需調整substr
的位置即可。 進行上述修改后(尤其是 2),您將通過更改這兩行來獲得沒有引號的條件
$pos1 = strpos($value, '===') + 5; // 5 includes the 3 equal signs, a space and the quote
$pos2 = strrpos($value, ')') - 2; // 2 includes the space and the quote
雖然這會得到您想要的結果,但它可能不適用於所有用例,因為有時您可能會添加一個空格,有時您可能不會。 更強大的解決方案是使用正則表達式。 在你的情況下,這將是這樣的:
foreach ($lines as $line) {
if(preg_match("/if\s*?\([\s\S]*?\=\=\s*?[\"|']([\S\s]*?)[\"|']\s*?\)/", $line, $matches)){
echo htmlspecialchars($matches[1]);
}
}
這個正則表達式字符串/if\\s*?\\([\\s\\S]*?\\=\\=\\s*?[\\"|']([\\S\\s]*?)[\\"|']\\s*?\\)/
做什么你的代碼的目標做的,但在一個更加穩健的方式=發現一個字符串if
可能的空間,一個(
一些文字,比較==
並且無論是在引號之間-無論是'
或"
。
為了讓它更健壯地選擇其他條件,嚴格相等, <
或>
或<=
, >=
,你可以做這樣的事情。
$conditionals=array();
foreach ($lines as $line) {
if(preg_match("/if\s*?\([\s\S]*?([\=|\>|\<][\=]{0,2})\s*?[\"|']([\S\s]*?)[\"|']\s*?\)/", $line, $matches)){
$conditionals[]=array(
'comparator'=>$matches[1],
'value'=>$matches[2]
);
}
}
foreach ($conditionals as $c){
echo htmlspecialchars($c['comparator']).' ';
echo htmlspecialchars($c['value']);
echo "<br/>";
}
這將適用於可能如下所示的 code.php 文件:
//code.php
<?php
$a = 'Data';
if(substr($a, 0, strlen("<SCRIPT"))=== "<SCRIPT" ) {
echo TRUE;
}
if(substr($a, 0, strlen("<SCRIPT"))== "equal" ) {
echo TRUE;
}
if(substr($a, 0, strlen("<SCRIPT"))<= "lesser or equal" ) {
echo TRUE;
}
if(substr($a, 0, strlen("<SCRIPT"))>= "greater or equal" ) {
echo TRUE;
}
if(substr($a, 0, strlen("<SCRIPT"))< "lesser" ) {
echo TRUE;
}
if(substr($a, 0, strlen("<SCRIPT"))>"greater" ) {
echo TRUE;
}
並將返回
=== <SCRIPT
== equal
<= lesser or equal
>= greater or equal
< lesser
> greater
編輯為非引用值提供更健壯的代碼......另一個編輯以捕獲變量值並將它們轉儲回。另一個編輯單引號變量和變量之間的空間
注意:捕獲字符串或變量的順序首先很重要,如果我們不小心可能會陷入一個粘性循環->變量中有字符串,字符串中有變量,變量中有字符串變量的字符串等...
這個想法是我們應該首先捕獲變量,評估這些變量中的任何變量(如果它們是雙引號字符串),我們不需要擔心 string-var inception 問題。
然后我們捕獲字符串 -> 然后替換字符串 THEN 替換變量。
更多注釋我們真正應該檢查的內容: 由於 PHP 只計算雙引號中的變量,我們應該在決定計算之前檢查字符串是否包含在雙引號和單引號中。 我已經為變量做了它。 它也可以很容易地轉換為字符串 - 通過捕獲引號,然后測試引號是單引號還是雙引號(或任何引號)。 我將把它作為正則表達式練習留給你。
另一個注意事項是我是故意這樣做的。 :p 當前用於捕獲變量的正則表達式適用於$a=3;
, $a =3;
但不是$a = 3;
或$a = 3 ;
或$a= 3 ;
, 很快。 添加它很容易,我把它留在了這里,所以你有機會通過添加這個簡單的條件來練習你的正則表達式技能。(編輯添加這個)希望這會有所幫助..
$file='';
$handle = fopen('code.php','r+');
if ($handle) {
while (($buffer=fgets($handle, 4096)) !== false) {
$file.=$buffer."\n";
}
if (!feof($handle)) {
die('error');
}
fclose($handle);
}
//take note of the use of single quotes to wrap this regex, as we do not want PHP parser to eval the $ in the regex string
preg_match_all('/\s*?(\$[\S]+?)\s*?\=\s*?(\"?[\S]+?\"?);/',$file,$matches, PREG_SET_ORDER);
$varval=array();
foreach($matches as $match){
$tmp=trim($match[2]);
if(substr($tmp,0,1)=='"' && substr($tmp,-1,1)=='"'){
//evaluate variables in string. we can evaluate with the current object as the variable should be declared first as of proper PHP syntax
$tmp=substr($tmp, 1,-1); //remove quotes
$tmp=replaceFromObject($tmp, $varval);
}else if(substr($tmp,0,1)=='\'' && substr($tmp,-1,1)=='\''){ // remove single quotes
$tmp=substr($tmp, 1,-1);
//no substitution of variables in single quotes just as PHP syntax
}
$varval[$match[1]]=$tmp; //we do not need to check if exists, because we should replace with the latest value.
}
/*
The below stores all quoted text and replace them with our own special variable %var0%, %var1%, %var2%.... %varN%.
This is because there could be cases like if("test == 3" == $a) or even worse if("if(test=3)" == $a), which will make regex/parsing tricky if we do not substitute these quoted text out just like a parser/compiler would.
Note: Something I didn't do. We should really first scan the whole text using preg_match to find if there are any text using this format of variables as well, to prevent collisions!
If there are, we can set a loop to check and append some character to our own special variable like %varrN%, %varrrN%, %varrrrN%...
until we find no collisions and it is safe to use. I will leave this simple regex exercise for you to do on your own. Create the regex to find the file for %varN%...
*/
preg_match_all("/\"([\s\S]*?)\"/", $file, $matches, PREG_SET_ORDER);
$stringvars=array();
$key="%var";
$count=0;
foreach($matches as $match){
if(!in_array($match[1], $stringvars)){
$stringvars[$key.$count.'%']=$match[1];
$file=preg_replace("/\"".preg_quote($match[1])."\"/", $key.$count.'%', $file); //take note of the change to preg_quote
$count++;
}
}
// now we parse the whole text for if(subject anycomparator value)
preg_match_all("/if\s*?\(([\s\S]*?)([\=|\>|\<][\=]{0,2})\s*?([\S\s]*?)\s*?\)/", $file, $matches,PREG_SET_ORDER);
$conditionals=array();
foreach($matches as $match){
$conditionals[]=array(
'subject'=>replaceFromObject(replaceFromObject(trim($match[1]),$stringvars),$varval),
//the order does matter, we replace the string first, then the variables, as there might be variables in the double quoted strings which we should evaluate
'comparator'=>$match[2],
'value'=>replaceFromObject(replaceFromObject(trim($match[3]),$stringvars),$varval),
);
}
foreach ($conditionals as $c){
echo htmlspecialchars($c['subject']).' ';
echo htmlspecialchars($c['comparator']).' ';
echo htmlspecialchars($c['value']);
echo "<br/>";
}
/* now this function can be used to replace both the quoted strings AND the variables */
function replaceFromObject($s, $obj){
foreach($obj as $key=>$value){
$s=preg_replace('/'.preg_quote($key).'/', $value, $s); //take note of the preg_quote as the string may contain regex keywords
}
return $s;
}
所以實際上你的代碼在我的服務器上沒有輸出任何東西(test.php)。 因此,我嘗試了另一種至少適用於您的 code.php 的方法,但是,它不像您自己的代碼那樣非常穩定,因為它沒有考慮以下幾點。
沒有想到的邏輯運算符:
<
, <=
, >
, >=
, ===
如果支持,則沒有多行
我的方法實際上不會拆分字符串,也不會剝離任何內容,但是它唯一要做的就是替換字符串文字。
<?php
$file = file_get_contents("test.php");
$curIdx = 0;
while($curIdx < strlen($file))
{
$ifIndex = strpos($file,"if", $curIdx);
if($ifIndex === false)
{
break;
}
$curIdx = $ifIndex+1;
$equalsIdx = strpos($file,"=",$curIdx);
if($equalsIdx === false)
{
break;
}
$curIdx = $equalsIdx+1;
for($i = $curIdx; $i<strlen($file); $i++)
{
if($file[$i] !== "=" && $file[$i] !== " ")
{
$curIdx = $i;
break;
}
}
$condition = substr($file,$curIdx,strpos($file,")",$curIdx)-$curIdx);
$condition = str_replace('"','',$condition);
echo htmlspecialchars($condition);
}
這輸出: <SCRIPT
對於您的腳本,我發現了幾個問題:
if(strpos($value, 'if') !== false)
必須有一個雙 ==
這樣一來,您將獲得以下輸出:
= "<SCRIPT"
要擺脫這種情況,只需檢查pos1
之后的字符是否是另一個=
if($value[$pos1] === "=")
{
$pos1++;
}
然后我們實際上可以完全刪除對sanitize_recursive
的調用,因為substr
從不返回數組。
現在擺脫,只需between
字符串between
調用str_replace
:
$between = substr($value, $startIndex, $length);
$between = str_replace('"','',$between);
echo htmlspecialchars($between);
我們有一個<SCRIPT
的輸出 - 需要調用htmlspecialchars
,否則您的瀏覽器將開始解釋這個標簽。
這給我們留下了以下文件:
<?php
$file = file_get_contents("test.php"); // Code.php the page that include the if condition
$lines = explode("\n", $file); // get each line of source code and store it in array ($lines)
foreach ($lines as $key => &$value) {
if(strpos($value, 'if') !== false) // check if the line have if statement
{
if(strpos($value, '==') !== false ) // check if the line compare two values
{
$pos1 = strpos($value, '==') + 2; // get the existence position of '==' + 2
if($value[$pos1] === "=")
{
$pos1++;
}
$pos2 = strrpos($value, ')'); // get the position of last ) in the line
$startIndex = min($pos1, $pos2);
$length = abs($pos1 - $pos2);
$between = substr($value, $startIndex, $length);
$between = str_replace('"','',$between);
echo htmlspecialchars($between); // will print: "<SCRIPT" with double quotation
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.