Get return values of code with tokenizer - php

I'm trying to parse PHP source code with the token_get_all(). So far everything worked out with that function, but now i need a way to get the return values of methods.
Identifying where a return is done isn't the problem. I just see no way of getting the piece of code that comes after the return value.
For example for this piece of code:
<?php
class Bla {
public function Test1()
{
$t = true;
if($t) {
return 1;
}
return 0;
}
public function Test2()
{
echo "bbb";
return; // nothing is returned
}
public function Test3()
{
echo "ccc";
$someval1 = 1;
$someval2 = 2;
return ($someval + $otherval)*2;
}
}
?>
I'm using get_token_all() to identify where a return is done:
$newStr = '';
$returnToken = T_RETURN;
$tokens = token_get_all($source);
foreach ($tokens as $key => $token)
{
if (is_array($token))
{
if (($token[0] == $returnToken))
{
// found return, now get what is returned?
}
else
{
$token = $token[1];
}
}
$newStr .= $token;
}
I have no clue how to get the piece of code that is actually returned. That is what i want to get.
Anyone any idea how i could do this?

Perhaps this might help. Though I curious to know what you are ultimately trying to do.
$tokens = token_get_all($str);
$returnCode = '';
$returnCodes = array();
foreach ($tokens as $token) {
// If return statement start collecting code.
if (is_array($tokens) && $token['0'] == T_RETURN) {
$returnCode .= $token[1];
continue;
}
// if we started collecting code keep collecting.
if (!empty($returnCode)) {
// if we get to a semi-colon stop collecting code
if ($token === ';') {
$returnCodes[] = substr($returnCode, 6);
$returnCode = '';
} else {
$returnCode .= isset($token[1]) ? $token[1] : $token;
}
}
}

Related

Create a recursive function with an array

I have a function but can't success to make it recursive.
This is my function without recursion :
function resolution_recursion($tab1, $tab2){
$solution = [];
foreach($tab2 as $nb2){
foreach($tab1 as $nb1){
if(($nb2 + $nb1)%2 != 1){
$solution[] = $nb2 + $nb1;
}
}
}
return $solution;
}
And I would like to make it recursive to make it work like :
$nb_ajout = [2];
$next = [[1,2],[3,4],[5,6],[7,8]];
resolution_recursion(
resolution_recursion(
resolution_recursion(
resolution_recursion($nb_ajout, $next[0]),
$next[1]),
$next[2]),
$next[3]);
I can't find the solution, if you can help me.
Something like this would do the trick...
function resolution_recursion($tab1, $tab2, $solution = [])
{
if (empty($tab2)) {
return $solution;
}
$set = array_shift($tab2);
foreach($set as $nb2){
foreach($tab1 as $nb1){
if(($nb2 + $nb1)%2 != 1){
$solution[] = $nb2 + $nb1;
}
}
}
if (!empty($tab2)) {
return resolution_recursion($tab1, $tab2, $solution);
}
return $solution;
}
You can find a demo here (the output however means absolutely nothing to me though so hopefully it means something to you lol)
I think I have found something, not using recursion :
function resolution_recursion($tab1, $tab2){
$solution = [];
$solution[-1] = $tab1;
foreach($tab2 as $key => $tab){
foreach($tab as $nb2){
foreach($solution[$key-1] as $nb1){
if(($nb2 + $nb1)%2 != 1){
$solution[$key][] = $nb2 + $nb1;
}
}
}
}
return $solution;
}

php include or require contents of a variable, not a file

I'm looking for a way to include or require the content of a variable, instead of a file.
Normally, one can require/include a php function file with either of these:
require_once('my1stphpfunctionfile.php')
include('my2ndphpfunctionfile.php');
Suppose I wanted to do something like this:
$contentOf1stFFile = file_get_contents('/tmp/my1stphpfunctionfile.php');
$contentOf2ndFFile = file_get_contents('/tmp/my2ndphpfunctionfile.php');
require_once($contentOf1stFFile);
require_once($contentOf2ndFFile);
Now, in the above example, I have the actual function files which I am loading into variables. In the real world scenario I'm actually dealing with, the php code in the function files are not stored in files. They're in variables. So I'm looking for a way to treat those variables as include/require treats the function files.
I'm new to php so please forgive these questions if you find them foolish. What I'm attempting to do here does not appear to be possible. What I ended up doing was using eval which I'm told is very dangerous and should be avoided:
eval("?>$contentOf1stFFile");
eval("?>$contentOf2ndFFile");
Content of $contentOf1stFFile:
# class_lookup.php
<?php
class Lookup_whois {
// Domain name which we want to lookup
var $domain;
// TLD for above domain, eg. 'com', 'net', etc...
var $tld;
// Array which contains information needed to parse the whois server response
var $tld_params;
// Sets to error code if something fails
var $error_code;
// Sets user-friendly error message if something goes wrong
var $error_message;
// For internal use mainly - raw response from the whois server
var $whois_raw_output;
function Lookup_whois($domain, $tld, $tld_params) {
$this->domain = $domain;
$this->tld = $tld;
$this->tld_params = $tld_params;
}
function check_domain_spelling() {
if (preg_match("/^([A-Za-z0-9]+(\-?[A-za-z0-9]*)){2,63}$/", $this->domain)) {
return true;
} else {
return false;
}
}
function get_whois_output() {
if (isset($this->tld_params[$this->tld]['parameter'])) {
$query = $this->tld_params[$this->tld]['parameter'].$this->domain.'.'.$this->tld;
} else {
$query = $this->domain.'.'.$this->tld;
}
$server = $this->tld_params[$this->tld]['whois'];
if (!$this->check_domain_spelling()) {
$this->error_message = 'Domain name is not correct, check spelling. Only numbers, letters and hyphens are allowed';
return false;
}
if (!$server) {
$this->error_message = 'Whois server name is empty, please check the config file';
return false;
}
$output = array();
$fp = fsockopen($server, 43, $errno, $errstr, 30);
if(!$fp) {
$this->error_code = $errno;
$this->error_message = $errstr;
fclose($fp);
return false;
} else {
sleep(2);
fputs($fp, $query . "\n");
while(!feof($fp)) {
$output[] = fgets($fp, 128);
}
fclose($fp);
$this->whois_raw_output = $output;
return true;
}
}
function parse_whois_data() {
if (!is_array($this->whois_raw_output) && Count($this->whois_raw_output) < 1) {
$this->error_message = 'No output to parse... Get data first';
return false;
}
$wait_for = 0;
$result = array();
$result['domain'] = $this->domain.'.'.$this->tld;
foreach ($this->whois_raw_output as $line) {
#if (ereg($this->tld_params[$this->tld]['wait_for'], $line)) {
if (preg_match($this->tld_params[$this->tld]['wait_for'],$line)) {
$wait_for = 1;
}
if ($wait_for == 1) {
foreach ($this->tld_params[$this->tld]['info'] as $key => $value) {
$regs = '';
if (ereg($value.'(.*)', $line, $regs)) {
if (key_exists($key, $result)) {
if (!is_array($result[$key])) {
$result[$key] = array($result[$key]);
}
$result[$key][] = trim($regs[1]);
} else {
$result[$key] = trim($regs[1]);
$i = 1;
}
}
}
}
}
return $result;
}
}
?>
Are there any other alternatives?
No there are no other alternatives.
In terms of security there is no difference if you include() a file or eval() the content. It depends on the context. As long as you only run your own code there is nothing "dangerous".

PHP Return true in foreach

I want to check if the user is using the default settings. In the example below, I'm trying to check if all "foreached" items return true. If a single foreached item doesn't return true, return false on the whole function.
private function is_using_default_settings() {
// returns a huge array with settings
$merged_preset = $this->options_merged();
foreach($merged_preset as $preset) {
if($preset[5] == 1) {
$section = 'general';
} elseif($preset[5] == 2) {
$section = 'advanced';
} elseif($preset[5] == 3) {
$section = 'technical';
}
$option = get_option($section);
if($preset[3] == $option[$preset[0]] && !is_null($preset[1])) {
return true;
}
}
return false;
}
I've been brainstorming for the past few days to get this sorted on my own, but sadly cannot get it to work. What is the best approach to this?
you can check when is false and block the full foreach then return value, if all is true return value true
try this:
private function is_using_default_settings() {
$returnValue = true;
$merged_preset = $this->options_merged();
foreach($merged_preset as $preset) {
if($preset[5] == 1) {
$section = 'general';
} elseif($preset[5] == 2) {
$section = 'advanced';
} elseif($preset[5] == 3) {
$section = 'technical';
}
$option = get_option($section);
if($preset[3] != $option[$preset[0]] || is_null($preset[1])) {
$returnValue = false;
break;
}
}
return $returnValue;
}
You should return false when any check fails in the foreach, otherwise return true.
function check()
{
foreach($arr as $v)
{
//check fails
if(fail of the check)
return false;
}
return true;
}

PHP says variable doesn't exist - even though it does

The following code gives me the following error, even thought the variable 'cache_path' has been defined at the top.
<b>Notice</b>: Undefined variable: cache_path in <b>C:\Users\Jan Gieseler\Desktop\janBSite\Scripts\Index.php</b> on line <b>20</b><br />
Here is the code;
header('Content-type: application/x-javascript');
$cache_path = 'cache.txt';
function getScriptsInDirectory(){
$array = Array();
$scripts_in_directory = scandir('.');
foreach ($scripts_in_directory as $script_name) {
if (preg_match('/(.+)\.js/', $script_name))
{
array_push($array, $script_name);
}
}
return $array;
}
function compilingRequired(){
if (file_exists($cache_path))
{
$cache_time = filemtime($cache_path);
$files = getScriptsInDirectory();
foreach ($files as $script_name) {
if(filemtime($script_name) > $cache_time)
{
return true;
}
}
return false;
}
return true;
}
if (compilingRequired())
{
}
else
{
}
?>
What could I do to fix this?
EDIT: I've thought that PHP makes variables which are in the 'main' scope available for functions, too. I guess, I was wrong. Thanks for the help.
I've fixed it by using the 'global' statement.
In order to fully understand this you will have to read up on Variable Scope, good luck!
header('Content-type: application/x-javascript');
$cache_path = 'cache.txt';
function getScriptsInDirectory(){
$array = Array();
$scripts_in_directory = scandir('.');
foreach ($scripts_in_directory as $script_name) {
if (preg_match('/(.+)\.js/', $script_name))
{
array_push($array, $script_name);
}
}
return $array;
}
function compilingRequired($cache_path){ //<-- secret sauce
if (file_exists($cache_path))
{
$cache_time = filemtime($cache_path);
$files = getScriptsInDirectory();
foreach ($files as $script_name) {
if(filemtime($script_name) > $cache_time)
{
return true;
}
}
return false;
}
return true;
}
if (compilingRequired($cache_path)) //<-- additional secret sauce
{
}
else
{
}
?>
Your $cache_path is not known inside functions. Either give it as a parameter like MonkeyZeus suggests or use a global $cache_path inside your function.
function compilingRequired(){
global $cache_path; // <------- like this
if (file_exists($cache_path))
{
$cache_time = filemtime($cache_path);
$files = getScriptsInDirectory();
foreach ($files as $script_name) {
if(filemtime($script_name) > $cache_time)
{
return true;
}
}
return false;
}
return true;
}

php regex failed, why?

The value is AbcDefg_123.
Here is the regex:
function checkAlphNum($alphanumeric) {
$return = false;
if((preg_match('/^[\w. \/:_-]+$/', $alphanumeric))) {
$return = true;
}
return $return;
}
Should allow a-zA-Z0-9.:_-/ and space in any order or format and does need all but at least one character.
EDIT: Sorry again, looks like var_dump() is my new best friend. I'm working with XML and it's passing the tag as well as the value.
#SilentGhost thnx for the tips.
It works for me too.
<?php
class RegexValidator
{
public function IsAlphaNumeric($alphanumeric)
{
return preg_match('/^[\w. \/:_-]+$/', $alphanumeric);
}
}
?>
and this is how I am testing it.
<?php
require_once('Classes/Utility.php');
$regexVal = new RegexValidator();
$list = array("abcd", "009aaa", "%%%%", "0000(", "aaaa7775aaa", "$$$$0099aaa", "kkdkdk", "aaaaa", "..0000", " ");
foreach($list as $value)
{
if($regexVal->IsAlphaNumeric($value))
{
echo $value . " ------>passed";
echo "<BR>";
}
else
{
echo $value . "------>failed";
echo "<br>";
}
}
?>
function checkAlphNum($alphanumeric) {
$return = false;
if((preg_match('/^[A-Za-z0-9\w. \/:_-]+$/', $alphanumeric))) {
$return = true;
}
return $return;
}
print checkAlphNum("AbcDefg_123");
Returns true.

Categories