Web form generator PHP class - empty property on foreach - php

I am currently building PHP class that generates web form for flexibility and localization issues. I am having difficulty assigning a key and value for dropdown input; for some reason the foreach seems does not get array variable ($country_list). Here is my code that I am having difficulty.
require_once('_include/country_list.php');
//drop down form class
class DropDown
{
function __construct ($form, $field_label, $field_name, $field_desc, $dropdown_data, $locale){
$this->form = $form;
$this->field_label = $field_label;
$this->field_name = $field_name;
$this->filed_desc = $filed_desc;
$this->dropdown_data = $dropdown_data;
$this->locale = $locale;
}
function getNotRequiredData(){
global $notReqArry; //http://stackoverflow.com/questions/1415577/accessing-variables-and-methods-outside-of-class-definitions
return $notReqArry[$this->locale];
}
function getValue(){
return $_POST[$this->field_name];
}
function dropdown(){
$selecedVal = $this->getValue();
$select_start = "<select name=\"$this->field_name\"><option value=\"\">$this->filed_desc</option>";
foreach ($this->dropdown_data as $key=>$value){
$selected = ($key == $selecedVal ? 'selected' : '');
$options = sprintf('<option value="%s" %s >%s</option>',$key,$selected,$value);
print $options;
}
$select_end = "</select>";
return $select_start . $options . $select_end;
}
function getLabel(){
$non_req = $this->getNotRequiredData();
$req = in_array($this->field_name, $non_req) ? '' : '*';
return $this->field_label ? $req . $this->field_label : '';
}
function __toString(){
$label = $this->getLabel();
$field = $this->dropdown();
return $label.$field;
}
}
function generateForm ($lang,$country_list){
switch($lang)
{
case 'en-US':
//create EN web form
echo $textField = new TextField($form, 'Note', 'form_note', '2', '20', '250', 'en-US');
//echo $textField_js = new JsTextField($textField, 'onkeyup', 'return checklength(this,contact_max_warning)', 'Characters typed:');
echo $dropDown = new DropDown ($form, 'Country', 'form_country', '--Select Country--', $country_list, 'en-US');
break;
case 'fr-FR':
//create FR web form
break;
case 'de-DE':
//create DE web form
break;
case 'ja-JP':
//create JA web form
break;
default:
//create default web form
print('foooo');
};
}
<form id="frm_verification" action="<?=$_SERVER['SCRIPT_NAME']?>" method="POST">
<?
$lang='en-US';
echo generateForm ($lang,$country_list);
?>
<p>
<input type="button" name="reset" value="Reset">
<input type="submit" name="submit" value="Submit">
</p>
</form>
and the array from country_list.php is like:
$country_main = array (
//Main 5 countries at first
//Those 5 countries are direct market of my previous company. you can modify whatever you want.
"US" => "United States",
"UK" => "United Kingdom",
"DE" => "Germany",
"FR" => "France",
"JP" => "Japan",
);
It does not work currently and I have check the error log, and it says:
"PHP Fatal error: Cannot access empty property in..."
I am sure that this is from my misunderstanding of class and its var or foreach statement.
Please help me to fix this; I really need help. (Yeah, I am really new on PHP)

foreach ($this->dropdown_data as $key->$value){
should read
foreach ($this->dropdown_data as $key=>$value){
Notice the change from -> to => in $key=>$value. Otherwise your code is trying to access property value in object key which is obviously invalid since key is not an object.

The variable you're referencing for your list of countries is misnamed:
echo generateForm ($lang,$country_list);
should be
echo generateForm ($lang,$country_main);
as that's how it's defined in country_list.php.

Related

Update function code igniter does not save changes

hi am making this edit function in my code igniter hmvc project. i am getting the value of the things i want to edit, and it is posted to the textbox i want to. but, i cannot save the changes. my model is this,
public function update(){
$sql = "UPDATE $this->table SET PROVINCE = ? WHERE PROV_ID = ?";
$input = array(
'PROVINCE' => $this->input->post('PROVINCE'),
'PROV_ID' =>$this->uri->segment(3)
);
// print_r($input);
// exit;
$query = $this->db->query($sql, $input);
return $query;
}
when i print_r the input, it says
Array ( [PROVINCE] => Province [PROV_ID] => )
i think dont get the uri value. how can i fix this?
here is my controller
/// EDIT
public function update(){
$data['content'] = $this->Provinces_Model->getrow();
$data['content_view'] = 'Provinces/edit_view';
$this->templates->admin_template($data);
}
public function update_row(){
if($this->Provinces_Model->update()){
redirect('Provinces/index');
}else{
$this->update();
}
}
}
here is my full model
//// EDIT
public function getrow(){
$this->db->where('PROV_ID', $this->uri->segment(3));
$query = $this->db->get($this->table);
return $query->row();
}
public function update(){
$sql = "UPDATE $this->table SET PROVINCE = ? WHERE PROV_ID = ?";
$input = array(
'PROVINCE' => $this->input->post('PROVINCE'),
'PROV_ID' =>$this->uri->segment(3)
);
// print_r($input);
// exit;
$query = $this->db->query($sql, $input);
return $query;
}
here is my edit view
<?php
echo form_open('Provinces/update_row');
?>
<p>
<label class="field" for="PROVINCE"><span>*</span>Province Name:</label>
<input type = "text" name="PROVINCE" class ="textbox-300" value= "<?php echo $content->PROVINCE; ?>">
<label class = "error"><?php echo form_error("PROVINCE"); ?></label>
</p>
<?php
echo form_submit('submit','Update');
echo form_close();
?>
here is the part of my table where i click to edit
<td><?php echo anchor("Provinces/update/$i->PROV_ID","<i class='fa fa-edit'>" ); ?></td>
Try this
public function update() {
$input = array(
'PROVINCE' => $this->input->post('PROVINCE'),
'PROV_ID' =>$this->uri->segment(3)
);
$this->db->where('prov_id',$input['PROV_ID']);
$this->db->update('province',$input);
}
get the all segments of URI in an array
For that use this line...
$segs = $this->uri->segment_array();
foreach ($segs as $segment)
{
echo $segment;
echo '<br />';
}
and use that specific key to get the ID or something else!!

domaincheck(TLD) what is available via PHP API

I'm building an domaincheck and it's working now. If i test for example example.com it says example.com is available of is not available.
But if it is not available i want my code to check the other ones (like example.org, example.nl, example.net, example.info etc.) to see if those are available or not.
This is my checker code
unset($command);
$command = array(
"command" => "DomainsCheckAvailability",
"domain" => htmlentities($_POST['domain']),
"tld" => htmlentities($_POST['tld'])
);
$api = new Versio_api();
$versio = $api->api_send( $command );
IF($versio['success']==0) {
echo("Fout opgetreden. Fout code: ".$versio['command_response_code'].". Fout text: ".$versio['command_response_message']."");
}
else
{
IF($versio['status']==1) {
echo "<div class='wrapper'>";
echo "<div class='beschikbaar'>";
echo $_POST['domain'].$_POST['tld']. "";
echo " is available.";
echo "</div'>";
echo "</div'>";
}
else
{
echo "<div class='wrapper'>";
echo "<div class='beschikbaar'>";
echo $_POST['domain'].$_POST['tld']. "";
echo " is not available.";
echo "</div'>";
echo "</div'>";
};
};
And these are my input fields:
<form action="domeincheck.php" method="post">
<input class="www" type="text" value="www." /></input>
<input class="invul" placeholder="uw websitenaam" type="text" name="domain"></input>
<select id="dropdownveld" name="tld">
<option value=".nl">.nl</option>
<option value=".com">.com</option>
<option value=".net">.net</option>
<option value=".be">.be</option>
<option value=".eu">.eu</option>
<option value=".org">.org</option>
<option value=".biz">.biz</option>
<option value=".info">.info</option>
</select>
<button class="btn_submit" type="submit" name="SubMit" class="input">Controleren</button>
</form>
Hope you can help!
Presumably you have a function that performs the check? I'll assume that's called domainAvailable(). All you need to do is create an array of the TLDs you want to check, then loop over them, adding to the end of the domain name you're checking, and check each one:
function domainAvailable($domain, $tld) {
$command = array(
"command" => "DomainsCheckAvailability",
"domain" => $domain,
"tld" => $tld
);
if ( $tld[0] == '.') {
$tld = substr($tld, 1);
}
$api = new Versio_api();
$res = $api->api_send( $command );
if ( $res['success'] )
return $res['status'] == 1;
return false;
}
$first_tld = $_POST['tld'];
$domain = $_POST['domain'];
if ( !domainAvailable($domain, $first_tld) ) {
echo '<br/>Domain '.htmlentities($domain.'.'.$first_tld).' is not available.<br/>What about these?<br/>';
$tlds = array('nl', 'com', 'net', 'be', 'eu', 'org', 'biz', 'info');
foreach($tlds as $tld) {
# Skip the first tld that was checked
if ( $tld != $first_tld) {
if ( domainAvailable($domain, $tld) )
echo '<br>'.htmlentities($domain).$tld.' is available';
else
echo '<br>'.htmlentities($domain).$tld.' is not available';
}
}
}
else {
echo '<br/>Domain '.htmlentities($domain.'.'.$first_tld).' is available';
}
Update: I've created a domainAvailable() function based on your updated code example.
Update 2: I've changed the code a bit. It should work provided you can get the domainAvailable() function correct, I've made a best guess on it based on the API docs, and the code you've posted.
You set the TLD in this piece of code:
$command = array(
[...]
"tld" => htmlentities($_POST['tld'])
);
In this case it comes from the $_POST. If you create an array which contains all TLD's you want to check, create a loop in which you put them as the "tld" in $command and perform
$api->api_send( $command );
You will get the response for each TLD.

PDO Update 1 column multiple rows with array

I am struggling to workout a good method to update one column of my wcx_options table.
The new data is sent fine to the controller but my function isn't working at all.
I assumed i could loop through each column by option_id updating with the values from the array.
The database:
I update the option_value column with the new information via a jQuery AJAX Call to a controller which then calls a function from the backend class.
So far i have the following code:
if(isset($_POST['selector'])) {
if($_POST['selector'] == 'general') {
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' && isset($_POST['token'])
&& $_POST['token'] === $_SESSION['token']){
$site_name = $_POST['sitename'];
$site_url = $_POST['siteurl'];
$site_logo = $_POST['sitelogo'];
$site_tagline = $_POST['sitetagline'];
$site_description = $_POST['sitedescription'];
$site_admin = $_POST['siteadmin'];
$admin_email = $_POST['adminemail'];
$contact_info = $_POST['contactinfo'];
$site_disclaimer = $_POST['sitedisclaimer'];
$TimeZone = $_POST['TimeZone'];
$options = array($site_name, $site_url, $site_logo, $site_tagline, $site_description, $site_admin, $admin_email,$contact_info, $site_disclaimer, $TimeZone);
// Send the new data as an array to the update function
$backend->updateGeneralSettings($options);
}
else {
$_SESSION['status'] = '<div class="error">There was a Problem Updating the General Settings</div>';
}
}
}
This is what i have so far in terms of a function (It doesnt work):
public function updateGeneralSettings($options) {
$i = 1;
foreach($options as $option_value) {
$where = array('option_id' => $i);
$this->queryIt("UPDATE wcx_options SET option_value='$option_value' WHERE option_id='$where'");
$i++;
}
if($this->execute()) {
$_SESSION['success'] = 'Updated General Settings Successfully';
}
}
With the given DB-layout i'd suggest to organize your data as assiciative array using the db fieldnames, like:
$option = array(
'site_name' => $_POST['sitename'],
'site_url' => $_POST['siteurl'],
// etc.
'timeZone' => $_POST['TimeZone']
);
And than use the keys in your query:
public function updateGeneralSettings($options) {
foreach($options as $key => $value) {
$this->queryIt("UPDATE wcx_options SET option_value='$value' WHERE option_name='$key'");
if($this->execute()) {
$_SESSION['success'] = 'Updated General Settings Successfully';
}
}
}
(However, are you sure, you do not want to have all options together in one row?)
Change your query, you try to use an array as where condition. In the syntax you used that won't work. Just use the counter as where condition instead of define a $where variable. Try this:
public function updateGeneralSettings($options) {
$i = 1;
foreach($options as $option_value) {
$this->queryIt("UPDATE wcx_options SET option_value='$option_value' WHERE option_id='$i'");
$i++;
}
if($this->execute()) {
$_SESSION['success'] = 'Updated General Settings Successfully';
}
}

Twitter Typeahead in CodeIgniter. Not passing array datum to hidden form field

I'm trying to use the typeahead.js Twitter Typeahead (not Bootstrap typeahead) to display names pulled from a mysql table using the CodeIgniter framework. The model also collects id values along with the name.
The controller and model seem to be presenting the correct array format.
Model
class People_model extends CI_Model{
function __construct() {
parent::__construct();
}
function get_person($name) {
$mode = $this->uri->segment(3);
$this->db->select("id, CONCAT(firstName,' ', lastName) AS name, type",FALSE);
$this->db->from('people');
if($mode == 'signin')
$this->db->where("status !=", "enter");
else
$this->db->where("status", "enter");
$this->db->like("concat(firstName,' ', lastName)", $name);
$this->db->order_by('name');
$query = $this->db->get();
if($query->num_rows > 0){
foreach ($query->result_array() as $row){
$new_row['value']=htmlentities(stripslashes($row['name']));
$new_row['id']=htmlentities(stripslashes($row['id']));
$row_set[] = $new_row; //build an array
}
}
echo json_encode($row_set); //format the array into json data
}
}
Controller (relevant functions)
function get_person() {
$this->config->set_item('disable_template', TRUE);
$this->load->model('People_model');
$name = $this->input->get_post();
$this->People_model->get_person($name);
}
function dosigninout() {
$mode = $this->uri->segment(3);
switch($mode) {
case 'signin':
$mode = 'enter';
break;
case 'signout':
$mode = 'exit';
break;
default:
$this->load->view("home/error", array('error' => "Invalid mode specified."));
}
$meeting = $this->_currentMeeting();
$person = $this->input->post('person_id');
if(!$this->_validPerson($person, $this->input->post('name'))) $this->load->view("home/error", array('error' => "You requested an operation with ".$this->input->post('name')." who has an ID of $person. The name and ID don't match."));
$this->db->insert("attendance", array('person_id' => $person, 'meeting_id' => $meeting['meetingID'], 'type' => $mode));
$this->db->where("id", $person);
$this->db->update("people", array('status' => $mode));
$redirectTo = (isset($_POST['redirect'])) ? $this->input->post('redirect') : false;
if($redirectTo) redirect($redirectTo);
else redirect('attendance');
}
Sample JSON data returned
[{"value":"Anna Woodhouse","id":"2"},{"value":"Elaine Woodhouse","id":"4"}]
View
$baseURL = base_url();
$extraHeadData = "";
?>
<h2><?=$title?></h2>
<p>Current meeting: <?=$meetingTitle?> on <?=$meetingDate?>.</p>
<?=form_open("attendance/dosigninout/$mode", array('id' => "signInOutForm"))?>
<fieldset>
<legend>Whom do you want to sign <?=($mode == "signin") ? 'in' : 'out'?>?</legend>
<div class="control-group">
<div class="controls">
<input type="hidden" name="person_id" id="person_id" value="" />
<input class="people-typeahead" type="text" id="typeahead" name="name" placeholder="person's full name"/>
</div>
</div>
</fieldset>
<div class="form-actions">
<?=form_submit('','Save changes','class="btn btn-primary"'); ?>
</div>
</form>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src="<?php echo $baseURL?>assets/js/typeahead.min.js"></script>
<script>
$(function($) {
$('input.people-typeahead').typeahead({
name: 'people',
remote: 'http://localhost/badgeentry/index.php/attendance/get_person',
dataType: 'json'
});
$("#people-typeahead").on("typeahead:selected typeahead:autocompleted", function(e,datum) {
$(person_id).val() = datum.id
});
});
</script>
In the form field I get the correct drop down list, but when an item is selected any new database entry has an id of "0" instead of the selected name id. I'm almost certain that this is an issue with the javascript code in the view not being correct, but quite frankly, I have no js skills to sort it out!
I see an issue here :
$(person_id).val() = datum.id
You are using jQuery's .val() incorrectly and the use of the selector is wrong too. It should look like :
$("#person_id").val(datum.id);
jQuery .val() documentation
I finally figured out how to get this working. Part of the problem was that I could find no examples of using typeahead.js in CodeIgniter that showed how the various script, view, controller and model components interact. I tried switching to Twitter bootstrap typeahead. However, despite finding references to using it with an arrays rather than a string, I still could not get a working solution.
In the end I went back to Twitter typeahead and started from scratch. I found this tutorial helped enormously:
Twitter Bootstrap typeahead.js with underscore.js Templating – A Tutorial - Alan Greenblatt
I'm posting what worked for me in case it can help anyone else with similar issues. This version also includes setting the remote source as a variable which allowed me to define it through PHP so that I could select data in the model based on the URL.
Model
class People_model extends CI_Model{
function __construct() {
parent::__construct();
}
function get_person($name) {
$modeinout = $this->uri->segment(3);
$this->db->select("id, CONCAT(firstName,' ', lastName) AS name, type",FALSE);
$this->db->from('people');
if($modeinout == 'signin'){
$this->db->where('status !=', 'enter');
}
else {
$this->db->where('status', 'enter');
}
$this->db->like("concat(firstName,' ', lastName)", $name);
$this->db->order_by('name');
$query = $this->db->get();
if($query->num_rows > 0){
foreach ($query->result_array() as $row){
$new_row['name']=htmlentities(stripslashes($row['name']));
$new_row['id']=htmlentities(stripslashes($row['id']));
$row_set[] = $new_row; //build an array
}
}
echo json_encode($row_set); //format the array into json data
}
Controller (relevant functions)
function signin() {
$this->load->helper("form");
$this->template->javascript('assets/js/underscore-min.js');
$this->template->javascript('assets/js/typeahead.min.js');
$data = $this->_currentMeeting();
$data['title'] = "Sign Someone In";
$data['attributes_form'] = array('id' => 'signInOutForm','class' => 'form-horizontal validate', 'enctype' => 'multipart/form-data');
$data['mode'] = 'signin';
$this->load->view("home/attendance/signinout", $data);
}
function signout() {
$this->load->helper("form");
$this->template->javascript('assets/js/underscore-min.js');
$this->template->javascript('assets/js/typeahead.min.js');
$data = $this->_currentMeeting();
$data['attributes_form'] = array('id' => 'signInOutForm','class' => 'form-horizontal validate', 'enctype' => 'multipart/form-data');
$data['id'] = '';
$data['title'] = "Sign Someone Out";
$data['mode'] = 'signout';
$this->load->view("home/attendance/signinout", $data);
}
function get_people() {
$this->config->set_item('disable_template', TRUE);
$this->load->model('People_model');
$name = $this->input->post('query');
$this->People_model->get_person($name);
}
function dosigninout() {
$mode = $this->uri->segment(3);
switch($mode) {
case 'signin':
$mode = 'enter';
break;
case 'signout':
$mode = 'exit';
break;
default:
$this->load->view("home/error", array('error' => "Invalid mode specified."));
}
$meeting = $this->_currentMeeting();
$person = $this->input->post('person_id');
if(!$this->_validPerson($person, $this->input->post('person_name'))) $this->load->view("home/error", array('error' => "You requested an operation with ".$this->input->post('person_name')." who has an ID of $person. The name and ID don't match."));
$this->db->insert("attendance", array('person_id' => $person, 'meeting_id' => $meeting['meetingID'], 'type' => $mode));
$this->db->where("id", $person);
$this->db->update("people", array('status' => $mode));
$redirectTo = (isset($_POST['redirect'])) ? $this->input->post('redirect') : false;
if($redirectTo) redirect($redirectTo);
else redirect('attendance');
}
View
<?php
$baseURL = base_url();
$extraHeadData = "";
?>
<h2><?=$title?></h2>
<p>Current meeting: <?=$meetingTitle?> on <?=$meetingDate?>.</p>
<?=form_open("attendance/dosigninout/$mode", array('id' => "signInOutForm",'class' => "form-horizontal validate"))?>
<input type="hidden" name="person_id" id="person_id">
<?php echo validation_errors(); ?>
<fieldset>
<legend>Whom do you want to sign <?=($mode == "signin") ? 'in' : 'out'?>?</legend>
<div class="control-group">
<div class="controls">
<input type="text" placeholder="person's full name" name="person_name" id="person_name" class="person-typeahead">
</div>
</div>
</fieldset>
<div class="form-actions">
<?=form_submit('','Save changes','class="btn btn-primary"'); ?>
</div>
</form>
<script>
var person_url="<?php echo site_url('attendance/get_people')."/".$mode;?>";
$(function($) {
_.compile = function(templ) {
var compiled = this.template(templ);
compiled.render = function(ctx) {
return this(ctx);
}
return compiled;
}
$('.person-typeahead').typeahead({
template: '<p><strong><%= name %></strong>: <%= id %></p>',
name: 'people',
valueKey: 'name',
engine: _,
remote: (person_url),
dataType: 'json'
}).on('typeahead:selected typeahead:autocompleted', function(event, datum) {
$('#person_id').val(datum.id);
$('#person_name').val(datum.name);
});
});
</script>
<?=jquery_validate('attendance/signout');?>

Function list of php file

How to get list of functions that are declared in a php file
You can get a list of currently defined function by using get_defined_functions():
$arr = get_defined_functions();
var_dump($arr['user']);
Internal functions are at index internal while user-defined function are at index user.
Note that this will output all functions that were declared previous to that call. Which means that if you include() files with functions, those will be in the list as well. There is no way of separating functions per-file other than making sure that you do not include() any file prior to the call to get_defined_functions().
If you must have the a list of functions per file, the following will attempt to retrieve a list of functions by parsing the source.
function get_defined_functions_in_file($file) {
$source = file_get_contents($file);
$tokens = token_get_all($source);
$functions = array();
$nextStringIsFunc = false;
$inClass = false;
$bracesCount = 0;
foreach($tokens as $token) {
switch($token[0]) {
case T_CLASS:
$inClass = true;
break;
case T_FUNCTION:
if(!$inClass) $nextStringIsFunc = true;
break;
case T_STRING:
if($nextStringIsFunc) {
$nextStringIsFunc = false;
$functions[] = $token[1];
}
break;
// Anonymous functions
case '(':
case ';':
$nextStringIsFunc = false;
break;
// Exclude Classes
case '{':
if($inClass) $bracesCount++;
break;
case '}':
if($inClass) {
$bracesCount--;
if($bracesCount === 0) $inClass = false;
}
break;
}
}
return $functions;
}
Use at your own risk.
You can use get_defined_functions() before and after you include the file, and look at what gets added to the array the second time. Since they appear to be in order of definition, you can just use the index like this:
$functions = get_defined_functions();
$last_index = array_pop(array_keys($functions['user']));
// Include your file here.
$functions = get_defined_functions();
$new_functions = array_slice($functions['user'], $last_index);
You can use the get_defined_functions() function to get all defined function in your current script.
See: http://www.php.net/manual/en/function.get-defined-functions.php
If you want to get the functions defined in another file, you can try using http://www.php.net/token_get_all like this:
$arr = token_get_all(file_get_contents('anotherfile.php'));
Then you can loop through to find function tokens with the symbols defined. The list of tokens can be found http://www.php.net/manual/en/tokens.php
If you're not worried about catching some commented out ones, this might be the simplest way:
preg_match_all('/function (\w+)/', file_get_contents(__FILE__), $m);
var_dump($m[1]);
I wrote this small function to return the functions in a file.
https://gist.github.com/tonylegrone/8742453
It returns a simple array of all the function names. If you're calling it in the particular file you want to scan, you can just use the following:
$functions = get_functions_in_file(__FILE__);
I solved this problem with array_diff
$funcs = get_defined_functions()["user"];
require_once 'myFileWithNewFunctions.php'; // define function testFunc() {} here
var_dump( array_values( array_diff(get_defined_functions()["user"], $funcs) ) )
// output: array[ 0 => "test_func"]
Update
To get the "real" functions name try this
foreach($funcsDiff AS $newFunc) {
$func = new \ReflectionFunction($newFunc);
echo $func->getName(); // testFunc
}
Well for what ever reason if you need to do this I show you:
Example file: Functions.php (I just wrote some random shit does not Mather it works with everything)
<?php
// gewoon een ander php script. door het gebruiken van meerdere includes kun je gemakkelijk samen aan één app werken
function johannes($fnaam, $mode, $array){
switch ($mode) {
case 0:
echo "
<center>
<br><br><br><br><br>
he johannes!<br><br>
klik hier voor random text:<br>
<input type='submit' value='superknop' id='btn' action='randomding' level='0' loadloc='randomshit' />
<p id='randomshit'></p>
</center>
";
break;
case 1:
echo "bouw formulier";
break;
case 2:
echo "verwerk formulier";
break;
default:
echo "[Error: geen mode gedefinieerd voor functie '$fnaam'!]";
}
}
function randomding($fnaam, $mode, $array){
$randomar = array('He pipo wat mot je!','bhebhehehehe bheeeee. rara wie ben ik?','poep meloen!','He johannes, wat doeeeeee je? <input type="text" name="doen" class="deze" placeholder="Wat doe je?" /> <input type="button" value="vertellen!" id="btn" action="watdoetjho" level="0" loadloc="hierzo" kinderen="deze"> <p id="hierzo"></p>','knopje de popje opje mopje','abcdefghijklmnopqrstuvwxyz, doe ook nog mee','Appien is een **p!!!!!! hahhahah<br><br><br><br> hahaha','Ik weet eiegelijk niks meer te verzinnen','echt ik weet nu niks meer','nou oke dan[[][(!*($##&*$*^éäåðßð','he kijk een microboat: <br> <img src="https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcS_n8FH6xzf24kEc31liZF6ULHCn2IINFurlFZ_G0f0_F4sLTi74w" alt="microboat" />');
$tellen = count($randomar);
$tellen--;
$rand = rand(0, $tellen);
echo $randomar[$rand];
}
function watdoetjho($fnaam, $mode, $array){
$dit = $array['doen'];
echo "Johannes is: $dit";
}
?>
We have 3 functions inside here:
johannes
randomding
watdoetjho
But we also call these functions:
count
rand
If we use get_defined_functions we will get all functions inside scope of script. Yes the PHP functions are separated from the user declared ones but still we want from a specific file.
If we use token_get_all we will receive a large amount of data we need to separate first.
I found these number which we need to make some connections inside the array to match the user functions. Otherwise we will have a list including all of php functions which are called upon.
The numbers are:
334 (List of all the user declared functions)
307 (List of all the function names)
If we filter the array to take all the 334 elements we have this:
334 -|- function -|- 5
But we need the function name and all the array elements are in relation with the 3rd value. So now we need to filter all the array elements which match the 3rd value (5) and the constant number 307.
This will give us something like this:
307 -|- johannes -|- 5
Now in PHP it will look like this:
<?php
error_reporting(E_ALL ^ E_NOTICE); // Or we get these undefined index errors otherwise use other method to search array
// Get the file and get all PHP language tokens out of it
$arr = token_get_all(file_get_contents('Functions.php'));
//var_dump($arr); // Take a look if you want
//The array where we will store our functions
$functions = array();
// loop trough
foreach($arr as $key => $value){
//filter all user declared functions
if($value[0] == 334){
//Take a look for debug sake
//echo $value[0] .' -|- '. $value[1] . ' -|- ' . $value[2] . '<br>';
//store third value to get relation
$chekid = $value[2];
}
//now list functions user declared (note: The last check is to ensure we only get the first peace of information about the function which is the function name, else we also list other function header information like preset values)
if($value[2] == $chekid && $value[0] == 307 && $value[2] != $old){
// just to see what happens
echo $value[0] .' -|- '. $value[1] . ' -|- ' . $value[2] . '<br>';
$functions[] = $value[1];
$old = $chekid;
}
}
?>
Result in this case is:
307 -|- johannes -|- 5
307 -|- randomding -|- 31
307 -|- watdoetjho -|- 43
To get list of defined and used functions in code, with small useful file manager, you can use code below. Enjoy!
if ((!function_exists('check_password'))||(!check_password()) ) exit('Access denied.'); //...security!
echo "<html><body>";
if (!$f) echo nl2br(htmlspecialchars('
Useful parameters:
$ext - allowed extensions, for example: ?ext=.php,css
$extI - case-insensitivity, for example: ?extI=1&ext=.php,css
'));
if (($f)&&(is_readable($_SERVER['DOCUMENT_ROOT'].$f))&&(is_file($_SERVER['DOCUMENT_ROOT'].$f))) {
echo "<h3>File <strong>$f</strong></h3>\n";
if(function_exists('get_used_functions_in_code')) {
echo '<h3>Used:</h3>';
$is=get_used_functions_in_code(file_get_contents($_SERVER['DOCUMENT_ROOT'].$f));
sort($is);
$def=get_defined_functions();
$def['internal']=array_merge($def['internal'], array('__halt_compiler', 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'finally', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while'));
foreach ($def['user'] as &$e) $e=strtolower($e); unset($e);
foreach ($is as &$e) if (!in_array(strtolower($e), $def['internal'], TRUE)) $e='<span style="color: red">'.$e.'</span>'; unset($e); //user-defined functions will be red
echo implode('<br />'.PHP_EOL,$is);
}
else echo "Error: missing function 'get_used_functions_in_code' !";
if(function_exists('get_defined_functions_in_code')) {
echo '<br /><h3>Defined:</h3>';
$is=get_defined_functions_in_code(file_get_contents($_SERVER['DOCUMENT_ROOT'].$f));
sort($is);
echo implode('<br />',$is);
}
else echo "Error: missing function 'get_defined_functions_in_code' !";
}
/*
File manager
*/
else {
if (!function_exists('select_icon')) {
function select_icon($name) {$name = pathinfo($name); return '['.$name["extension"].']';}
}
if($ext) $extensions=explode(',',strrev($ext));
if(!$f) $f=dirname($_SERVER['PHP_SELF']);
echo "<h3>Dir ".htmlspecialchars($f)."</h3><br />\n<table>";
$name=scandir($_SERVER['DOCUMENT_ROOT'].$f);
foreach($name as $name) {
if (!($fileOK=(!isset($extensions)))) {
foreach($extensions as $is) if (!$fileOK) $fileOK=((strpos(strrev($name),$is)===0)||($extI &&(stripos(strrev($name),$is)===0)));
}
$is=is_dir($fullName=$_SERVER['DOCUMENT_ROOT']."$f/$name");
if ($is || $fileOK) echo '<tr><td>'.select_icon($is ? 'x.folder' : $name).' </td><td> '.($is ? '[' : '').''.htmlspecialchars($name).''.($is ? ']' : '').'</td>';
if ($is) echo '<td> </td><td> </td>';
elseif ($fileOK) echo '<td style="text-align: right"> '.number_format(filesize($fullName),0,"."," ").' </td><td> '.date ("Y.m.d (D) H:i",filemtime($fullName)).'</td>';
if ($is || $fileOK) echo '</tr>'.PHP_EOL;
}
echo "\n</table>\n";
}
echo "<br /><br />".date ("Y.m.d (D) H:i")."</body></html>";
return;
/********************************************************************/
function get_used_functions_in_code($source) {
$tokens = token_get_all($source);
$functions = array();
$thisStringIsFunc = 0;
foreach($tokens as $token) {
if(($token[0]!=T_WHITESPACE)&&((!is_string($token))||($token[0]!='('))) unset($func);
if((is_array($token))&&(in_array($token[0],array(T_EVAL,T_EXIT,T_INCLUDE,T_INCLUDE_ONCE,T_LIST,T_REQUIRE,T_REQUIRE_ONCE,T_RETURN,T_UNSET)))) {$token[0]=T_STRING;$thisStringIsFunc=1;}
switch($token[0]) {
case T_FUNCTION: $thisStringIsFunc=-1;
break;
case T_STRING:
if($thisStringIsFunc>0) {
if (!in_array(strtoupper($token[1]),$functionsUp)) {$functions[]=$token[1];$functionsUp[]=strtoupper($token[1]);}
$thisStringIsFunc = 0;
} elseif ($thisStringIsFunc+1>0) {
$func = $token[1];
} else $thisStringIsFunc = 0;
break;
case '(':if($func) if(!in_array(strtoupper($func),$functionsUp)) {$functions[]=$func;$functionsUp[]=strtoupper($func);}
}
}
return $functions;
}
/********************************************/
function get_defined_functions_in_code($source) {
$tokens = token_get_all($source);
... then Andrew code (get_defined_functions_in_file) (https://stackoverflow.com/a/2197870/9996503)
}
Finding string (eg. Function names) in a file is simple with regex.
Just read the file and parse the content using preg_match_all.
I wrote a simple function to get list of functions in a file.
https://gist.github.com/komputronika/f92397b4f60870131ef52930faf09983
$a = functions_in_file( "mylib.php" );
The simplest thing (after I saw #joachim answer) is to use get_defined_functions and then only watch for the 'user' key (which contains an array of user-defined methods)
This is the code that helped me solved the problem
<?php
//Just to be sure it's empty (as it should be)
$functions = get_defined_functions();
print_r($functions['user']);
//Load the needed file
require_once '/path/to/your/file.php';
//display the functions loaded
$functions2 = get_defined_functions();
print_r($functions2['user']);
To retrieve also the params definition: (Source in comments)
Array
(
[0] => function foo ( &&bar, &big, [$small = 1] )
[1] => function bar ( &foo )
[2] => function noparams ( )
[3] => function byrefandopt ( [&$the = one] )
)
$functions = get_defined_functions();
$functions_list = array();
foreach ($functions['user'] as $func) {
$f = new ReflectionFunction($func);
$args = array();
foreach ($f->getParameters() as $param) {
$tmparg = '';
if ($param->isPassedByReference()) $tmparg = '&';
if ($param->isOptional()) {
$tmparg = '[' . $tmparg . '$' . $param->getName() . ' = ' . $param->getDefaultValue() . ']';
} else {
$tmparg.= '&' . $param->getName();
}
$args[] = $tmparg;
unset ($tmparg);
}
$functions_list[] = 'function ' . $func . ' ( ' . implode(', ', $args) . ' )' . PHP_EOL;
}
print_r($functions_list);
do include to the file and try this :
$functions = get_defined_functions();
print_r($functions['user']);

Categories