get a value from key value pair list in php - php

I want to display a specific value from key value list..
here is my code:
if (isset($_POST) && count($_POST)>0 )
{
foreach($_POST as $paramName => $paramValue) {
echo "<br/>" . $paramName . " = " . $paramValue;
}
}
ouput
ORDERID = ORDS3700373
TXNAMOUNT = 200.00
CURRENCY = INR
TXNID = 32221284
BANKTXNID = 475815
STATUS = TXN_SUCCESS
RESPCODE = 01
RESPMSG = Txn Successful.
TXNDATE = 2017-01-10 18:13:25.0
GATEWAYNAME = WALLET
BANKNAME =
PAYMENTMODE = PPI
CHECKSUMHASH =
here I want to display only ORDERID and TXNID.. How do I get that value?

You can easily access post values by it's field name instead of looping through all post elements. Simply access that elements directly as below:
if(isset($_POST['ORDERID'])) {
echo 'ORDERID = '.$_POST['ORDERID'];
}
if(isset($_POST['TXNID'])) {
echo 'TXNID= '.$_POST['TXNID'];
}

Moving comments to an answer.
You do not need to loop post it is just a global array. You can access the values at any of the keys like any associative array because that is what it is. Likewise these value can be used like any other
if(isset($_POST['ORDERID'])){
$orderid = $_POST['ORDERID'];
}
if(isset($_POST['TXNID'])){
$txnid = $_POST['TXNID'];
}
// Should use htmlspecialchars() or htmlentities() here
// but didn't want to confuse OP. It is for security.
echo "ORDERID is: " . $orderid . " and TXNID is: " . $txnid;
A note for security never trust user input and sanitize all $_POST variables before echoing or persisting. There are far better article out on the internet than I can summarize here.

You can use if condition in the loop like this
if (isset($_POST) && count($_POST)>0 )
{
foreach($_POST as $paramName => $paramValue) {
if($paramName == 'ORDERID' || $paramName == 'TXNID')
echo "<br/>" . $paramName . " = " . $paramValue;
}
}

add an if like
if($paramName == "ORDERID" || $paramName == "TXNID") {
after foreach, remeber to close it after echo statement line

Don't overcomplicate a trivial task with a loop.
Just drop the loop and echo the two values directly:
// Assuming the two values are expected to come in pair:
if(isset($_POST['ORDERID']) && isset($_POST['TXNID'])) {
echo "<br/>ORDERID = " . $_POST['ORDERID'];
echo "<br/>TXNID = " . $_POST['TXNID'];
}
If you insist on having a loop, then you can go through the property names which you need
foreach(array('ORDERID', 'TXNID') as $paramName) {
if(isset($_POST[$paramName])) {
echo "<br/>" . $paramName . " = " . $_POST[$paramName];
}
}

Related

PHP/PDO Dynamically binding values (invalid param count error)

I was tasked (stuck) with trying to update an old mysql_query code to be PDO compliant.
This was (is) a messy search form, that was dynamically creating the query string based on field values if (or not) there were any key words submitted along with the form. (ie: any key word is parsed by spaces, and used for BOTH column searches)
So if a search term of 'dog' was entered.. it would search name & title for the key word of 'dog'..
I think I made my way through it.. keeping the main 'function' in-tact for the most part.. and updating when I needed to.
My approach was to take the function that is dynamically adding more criteria to the query string.... and also add this value field name & value to an array, so I can loop through it later on and dynamically bindValues with it..
I am now stick with the ever so popular Invalid Parameters error!!
However its not saying the counts dont match.. its saying it was defined at all.
I'm not clear where my error is stemming from.. (or how to easily see the computed/parsed query string.. or the actual bound parameters) I can just output the sql statement (before it parses any data).. or echo out my values in the array I loop through to (potentially) bind the data to the PDO call..
WHen I echo out the query (string).. and even the values I am attempting to dynamically bind... they all look legit to me:
Query Check: SELECT * FROM pid_information WHERE 1=1 AND (((title LIKE :title0) OR (name LIKE :name0)) AND ((title LIKE :title1) OR (name LIKE :name1))) ORDER BY title, name, link
PARAM CHECK: ':title0' -> %cat%
PARAM CHECK: ':name0' -> %cat%
PARAM CHECK: ':title1' -> %dog%
PARAM CHECK: ':name1' -> %dog%
To re-cap:
addCriteria() function is used to dynamically (concat) add to the query 'string'
I also populate an array to be used later to loop through and bindValues with.
Yes I know it is long.. yes I know ugly.. (please, just bear with me!) LOL
//dynamically add criteria to query
$boundSearchValues = array();
function addCriteria($targetFields, $criteriaString, $targetOperator='LIKE'){
global $boundSearchValues;
$fieldCount = 0;
$tempString = "";
if($criteriaString != ""){
$criteriaArray = explode(" ", $criteriaString);
$tempString .= " AND (";
foreach($criteriaArray as $criteriaIndex => $criteriaValue){
//is array of fields
if(is_array($targetFields)){
$tempString .= "(";
foreach ($targetFields as $targetField => $fieldName){
if($targetOperator != 'LIKE') {
$tempString .= "($fieldName ".$targetOperator." :". $fieldName.$fieldCount .")";
$boundSearchValues[] = [$fieldName.$fieldCount, $criteriaValue];
}else{
$tempString .= "($fieldName LIKE :". $fieldName.$fieldCount .")";
$boundSearchValues[] = [$fieldName.$fieldCount, '%'.$criteriaValue.'%'];
}
if($targetField+1 < count($targetFields)){
$tempString .= " OR ";
}
}
$tempString .= ")";
if($criteriaIndex+1 < count($criteriaArray)){
$tempString .= " AND ";
}
//not an array of fields
}else{
if($targetOperator != 'LIKE') {
$tempString .= "(".$targetFields . $targetOperator . " :" . $fieldName.$fieldCount . ")";
$boundSearchValues[] = [$fieldName.$fieldCount, $criteriaValue];
} else {
$tempString .= "(". $targetFields . " LIKE " . $fieldName . $fieldCount . ")";
$boundSearchValues[] = [$fieldName.$fieldCount, '%'.$criteriaValue.'%'];
}
}
$fieldCount++; //increment counter
}
$tempString .= ")";
}
return $tempString;
}
//start serach query
$searchDetails_sql = "SELECT * FROM $tablename ";
//dynamically update query string
if($clean_keywords != "") {
$whereClause = addCriteria(array('title', 'name'), $clean_keywords);
}else{
if($title != "" && $title != "all"){
$whereClause .= " AND title = :" . $title;
}
if($name != "" && $name != "all"){
$whereClause .= " AND name = :" . $name;
}
if($link != "" && $link != "all"){
$whereClause .= " AND link = :" . $link ;
}
}
$searchDetails_sql .= "WHERE 1=1 ". $whereClause;
$searchDetails_sql .= " ORDER BY title, name, link";
$searchDetails_stmt = $conn->prepare($searchDetails_sql);
//dynamically bind values
for($i=0; $i<count($boundSearchValues); $i++){
$searchDetails_stmt->bindValue("':".$boundSearchValues[$i][0] ."'", $boundSearchValues[$i][1]);
//$searchDetails_stmt->bindParam("':".$boundSearchValues[$i][0] ."'", $boundSearchValues[$i][1]);
echo '<br>PARAM CHECK: ' . $boundSearchValues[$i][0] . " / " . $boundSearchValues[$i][1];
}
$searchDetails_stmt->execute();
$searchDetails_stmt->setFetchMode(PDO::FETCH_ASSOC);
$searchDetails = $searchDetails_stmt->fetchAll(); //returns multi-dimensional array (and correct count)
I think you just messed up the string concatenation in this line
$searchDetails_stmt
->bindValue("':".$boundSearchValues[$i][0] ."'", $boundSearchValues[$i][1]);
You dont actually need the : so you could do this
$searchDetails_stmt
->bindValue($boundSearchValues[$i][0], $boundSearchValues[$i][1]);
Or fix the concatenation and keep the :
$searchDetails_stmt
->bindValue(":".$boundSearchValues[$i][0], $boundSearchValues[$i][1]);

how can i change the array value from if else statement inside a loop?

i've been hours trying to assign value in the array but every iteration the array is set to 0 and i can't understand why , here's the code ...
$AurQ = array();
$prod = '';
while ($NOTIFY = $notification->fetch_assoc()) {
print_r($AurQ);
if ($NOTIFY['notification_type_ID'] == 1) {
if (in_array($NOTIFY['qID'], $AurQ, true)) {
echo "exist";
continue;
} else {
$AurQ[] = $NOTIFY['qID']; // Adding the value to the array
$prod .= '<li><a href="http://localhost/website/link/' . $NOTIFY['qID'] . '"> <span class="AskIcon"></span><span class="noti_announce">';
$prod .= '<span class="unB">' . $NOTIFY['first_name'] . ' ' . $NOTIFY['last_name'] . '</span> ' . $NOTIFY['notify_name_en'] . ' "' . $NOTIFY['q_title'] . '"</span>';
$prod .= '<span class="noti_time"><span class="icon"></span>' . time_elapsed_string($NOTIFY['time']) . '</span></a></li>';
} // end of if doesn't exist in Array List
} //end of if
} // end of loop
The problem appears to be that you're pushing a value to the array only after checking if it already exists in that array, which it doesn't given that you're initializing it as an empty array just above it.
So, there's a logic error here, and depending on what you're trying to do, it can be fixed by moving the $AurQ[] = $NOTIFY['qID'] ; line into the else statement, or by changing your if statement from if (in_array($NOTIFY['qID'], $AurQ, true)) { to if (!in_array($NOTIFY['qID'], $AurQ, true)) {.
As you didn't mention an issue with things displaying when you didn't want them to, I'm going to assume you're looking for the former solution as opposed to the latter. So, your code will wind up looking something like this:
$AurQ = array();
$prod ='';
while($NOTIFY = $notification->fetch_assoc()) {
if ($NOTIFY['notification_type_ID'] == 1) {
if (in_array($NOTIFY['qID'], $AurQ, true)){ //If it's ALREADY in the array
echo "exist";
continue;
} else { //Otherwise we need to add it, and display it
$AurQ[] = $NOTIFY['qID'] ; // Adding the value to the array
$prod .= '<li><a href="http://localhost/website/link/'.$NOTIFY['qID'].'"> <span class="AskIcon"></span><span class="noti_announce">';
$prod .= '<span class="unB">'.$NOTIFY['first_name'].' '.$NOTIFY['last_name'].'</span> '.$NOTIFY['notify_name_en'].' "'.$NOTIFY['q_title'].'"</span>';
$prod .= '<span class="noti_time"><span class="icon"></span>'.time_elapsed_string($NOTIFY['time']).'</span></a></li>';
}// end of if doesn't exist in Array List
}//end of if
} // end of loop
Given your code you just need to move $AurQ[] = $NOTIFY['qID']; to else block.
Currently, $AurQ[] is empty and if block will never run because in_array($NOTIFY['qID'], $AurQ, true) will always return false.

Why my array element is re-declaring?

I have declared static array $error whose elements are defining in function validate
static $error = array();
if(!empty($_POST) && validate())
{
$sql = mysql_query("INSERT INTO `table-name` SET category = " . $_POST['category'] . ", brand = " . $_POST['brand'] . ", product = '" . $_POST['p_name'] . "', location = " . $_POST['location'] . ", image = '" . $_POST['image'] . "', sku = '" . $_POST['sku'] . "'");
}
function validate()
{
if ((strlen($_POST['p_name']) < 3) || (strlen($_POST['p_name']) > 32))
{
$error["p_name"] = "Please enter Vendor name of 3 to 32 characters." ;
}
.
.
.
}
but the problem is when i am using the updated $error element like $error['p_name'] in below html, it is showing undefined index p_name.
<td>
<?php if(isset($error["p_name"])){ ?><span class="error"><?php echo $error["p_name"]; ?></span><?php } ?>
</td>
and when I print $error['p_name'] element within validate function it get printed with updated value.
Actually element - $error['p_name'] in validate function is defining a new element rather than creating a new array element of predefined $error array.
Well you didn't answer my comment. so it was the scope issue , Do not use global keyword. Use the Dependency Injection concept..
Pass your $error array variable as a reference to your function..
function validate(&$error) //<---- Like that. (See the & ?)
{
and when you do a call to your validate function make sure you pass the array too.
The reason you should really avoid using globals. Read this linked article.
use global keyword to tell php, that you are using global $error:
function validate()
{
global $error;
if ((strlen($_POST['p_name']) < 3) || (strlen($_POST['p_name']) > 32))
{
$error["p_name"] = "Please enter Vendor name of 3 to 32 characters." ;
}

Exiting a foreach loop and retrieve result

I'm working on a little project and I've gone brain dead, so I'm hoping someone here can help me defeat my coders block.
I'm trying to create a page using php that changes its content display depending on what (if any) value is passed to the page (Locations). I have created a safelist array which I've stored the different locations. First I check any value passed against the safe list, if its a match I display one set of content.
If it doesn't match I'm running a similarity test to check if theres maybe a simple typo and can still navigate people to the page I think they wanted but this is where I'm getting stuck.
I'm hoping that someone could type
www.example.co.uk/location.php <---- to load a generic location page
www.example.co.uk/location.php?loc=Bishops-Stortford <---- to load a targeted location page
www.example.co.uk/location.php?loc=Bishop-Stortford <---- to load a targeted location page despite mispelling providing its a 90% or more match
www.example.co.uk/location.php?loc=?php echo "I hacked your site"; ?> ---- hopefully my system will disarm nasty code injection
I'll post my code below so you can see what I've got.
<?php
$loc = "";
$safelist = array("Bishops Stortford", "Braintree", "Chelmsford", "Dunmow", "Harlow", "Hertford", "Saffron Walden", "Sawbridgeworth", "Stansted", "Ware",
"Essex", "Hertfordshire");
if(isset($_GET["loc"])) {
/* Gets the value of loc if set, replaces hyphens with spaces and capitalises first letters of words converting the rest to lowercase. */
$loc = ucwords(strtolower(str_replace("-", " ", $_GET["loc"])));
}
/* Is word in safelist */
if (in_array($loc, $safelist)) {
/* Yes */
if (($loc == "Essex") or ($loc == "Hertfordshire")) {
$county = True;
} else {
$county = False;
}
if ($county == False) {
echo "\"" . $loc . "\" is not a county";
}else{
echo "\"" . $loc . "\" is a county";
}
} else {
/* No, Is string 90% similar to any entry within the safelist? */
foreach ($safelist as $safeword) {
similar_text($safeword, $loc, $percent);
echo $safeword . " " . $loc . " " . $percent . "<br />";
if ($percent >= 90) {
}
}
?>
I can't think what to do for the if ($percent >=90). I know I want to exit the loop and get the result from the first 90% or more match I find but am not 100% sure how to do this.
Also whats the best way to deal with code injection like www.example.co.uk/location.php?loc=?php echo "I hacked your site"; ?>
I think this is what you want:
foreach ($safelist as $safeword) {
similar_text($safeword, $loc, $percent);
echo $safeword . " " . $loc . " " . $percent . "<br />";
if ($percent >= 90) {
$loc = $safeword;
$county = true;
break;
}
}
As long as you don't call eval() on user input, you don't have to worry about them injecting PHP statements. When you echo something, it's sent to the browser, it's not executed again by PHP. However, you should still sanitize the output, because it might contain HTML markup, perhaps even Javascript, which could hijack the user's browser. When displaying output on the page, use htmlentities() to encode it:
echo "Greetings, " . htmlentities($first_name);
To answer the second part of your question, I use htmlentities to output data directly to the screen from input and something like this function on the data before a save to a database:
function escape_value($value)
{
if($this->real_escape_string_exists)
{
if($this->magic_quotes_active){$value = stripslashes($value);}
$value = mysql_real_escape_string($value);
}
else
{
if(!$this->magic_quotes_active){$value = addslashes($value);}
}
return $value;
}
I think I would restructure it, something like this:
$loc = "";
$safelist = array("Bishops Stortford", "Braintree", "Chelmsford", "Dunmow", "Harlow", "Hertford", "Saffron Walden", "Sawbridgeworth", "Stansted", "Ware",
"Essex", "Hertfordshire");
if(isset($_GET["loc"])) {
/* Gets the value of loc if set, replaces hyphens with spaces and capitalises first letters of words converting the rest to lowercase. */
$loc = ucwords(strtolower(str_replace("-", " ", $_GET["loc"])));
}
$good = '';
if (in_array($loc, $safelist)) {
$good = $loc;
} else {
foreach ($safelist as $safeword) {
similar_text($safeword, $loc, $percent);
echo $safeword . " " . $loc . " " . $percent . "<br />";
if ($percent >= 90) {
$good = $safeword;
}
}
}
if ( ! empty($good)){
/* Yes */
if (($good == "Essex") or ($good == "Hertfordshire")) {
$county = True;
} else {
$county = False;
}
if ($county == False) {
echo "\"" . $good . "\" is not a county";
}else{
echo "\"" . $good . "\" is a county";
}
//And whatever else you want to do with the good location...
}
Like Barmar said, since you're not doing anything with the input value except for comparing it to an array, there's no risk of an attack in that way.

I need a character or string which will match ANY value in my table field

I have a form that requires the user to only fill out at least 1 (out of four) fields. They can then submit and get a search result based off of their input.
The problem is, I can't get a character to set my variables to that will match any database value. Here is my code for some context;
if (isset($_POST['buildname']) ||
isset($_POST['weapon']) ||
isset($_POST['category']) ||
isset($_POST['id']))
{
if ($_POST['buildname'] == "")
{
$buildname = ".*";
}
if ($_POST['weapon'] == "")
{
$weapon = ".*";
}
if ($_POST['category'] == "")
{
$category = ".*";
}
if ($_POST['id'] == "")
{
$id = ".*";
}
$buildname = sanitizeString($_POST['buildname']);
$weapon = ($_POST['weapon']);
$category = ($_POST['category']);
$id = ($_POST['id']);
$searchstring = "SELECT buildname,weapon,category,id,author FROM weapons " .
"WHERE buildname='$buildname' AND weapon='$weapon' AND category='$category' AND id='$id'";
As you can see, the code looks at if one of the variables is set, then submits a form. If a variable isn't set, it assigns a character of ".*" (which I thought would match anything). It then queries the database to match any rows. I get no results unless I enter EVERY field with a correct entry.
Any ideas?
Thanks!
I would not use %, instead do something like this
if (isset($_POST['buildname']) || isset($_POST['weapon']) || isset($_POST['category']) || isset($_POST['id'])){
$sqlArray = array();
if(isset($_POST['buildname'])){
$sqlArray[] = "buildname='" . mysqli_real_escape_string($connection,$_POST['buildname']) . "'";
}
if(isset($_POST['weapon'])){
$sqlArray[] = "weapon='" . mysqli_real_escape_string($connection,$_POST['weapon']) . "'";
}
if(isset($_POST['category'])){
$sqlArray[] = "category='" . mysqli_real_escape_string($connection,$_POST['category']) . "'";
}
if(isset($_POST['id'])){
$sqlArray[] = "id='" . mysqli_real_escape_string($connection,$_POST['id']) . "'";
}
$searchstring = "SELECT buildname,weapon,category,id,author FROM weapons " .
"WHERE " . implode(' AND ', $sqlArray);
}
The wildcard character for MySQL is: %
The query you are executing, you "thought would match anything" wont. The statement uses no regular expressions.
WHERE buildname='$buildname' AND weapon='$weapon'
Which is essentially saying you need to have the following fields equal their string value of:
WHERE buildname='.*' AND weapon='.*'
I doubt you have any building with a name of .*.
It would be better to not filter on that field. basically remove the WHERE cause criteria if the variable is not defined.
You can do this dynamically, buliding the SQL statement only when you need to filter by that field.
if (isset($_POST['somevalue']) && ! empty($_POST['somevalue'])) {
$where .= 'column_name = ?';
$values[] = sanitizeString($_POST['somevalue]);
}
I've also used positional parameters which assumes you will be using the PDO or MySQLi libraries for querying.
No, you are using = operator, that only compares 2 values. In your case it will search for '.*' - and fail. If you want to ignore the fields, that were not filled, just don't put them into the query: no need for regexps. So, if the weapon and category are missing, your query should be like this
$searchstring = 'SELECT buildname,weapon,category,id,author FROM weapons WHERE ';
$fields = array('buildname', 'weapon', 'category', 'id');
$data = array();
foreach($fields as $value)
{
if (isset($_POST[$value]) && ($_POST[$value] != "") )
{
$data[] = sanitizeString($_POST[$value]);
}
}
$n = count($data);
if($n > 0)
{
$searchstring .= implode(' AND ', $data);
//do MySQL request and output result
}
Don't overcomplicate simple things. Also your code is vulnerable to SQL injection as some fields are not escaped.
You can do it like this:
$fields = array('buildname', 'weapon', 'category', 'id');
$sql = 'SELECT buildname, weapon, category, id, author FROM weapons';
$prefix = ' WHERE ';
foreach ($fields as $field) {
if (isset($_POST[$field]) && strlen($_POST[$field])>1) {
$sql .= $prefix . $field . '=\''
. sanitizeString($_POST[$field]) . '\'';
$prefix = ' AND ';
}
}
if ($prefix == ' AND ') {
// send the query
}
Notice: if you want to perform search with incomplete values, you could use LIKE instead of =, example:
$sql .= $prefix . $field . ' LIKE \'%' . sanitizeString($_POST[$field]) . '%\'';
But keep in mind that LIKE is slower than =

Categories