Multiple variable declaration in PHP - php

How can I declare multiple variables in a single variable in PHP?
$dtAno = ($detData == 'yyyy') ? "to_char(noti_infrcod, 'YYYY')" : " NULL ";
$dtMes .= ($detData == 'mm/yyyy') ? "to_char(noti_infrcod, 'MM')" : " NULL ";
$dtAno .= ($detData == 'dd/mm/yyyy') ? "to_char(noti_infrcod, 'DD')" : " NULL ";
$dtHora .= ($detData == 'HH24/dd/mm/yyyy') ? "to_char(noti_infrcod, 'HH24')" : " NULL ";
$dtSelect = $dtAno.$dtMes.$dtDia.$dtHora;

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]);

MySQL Insert query becomes slow on progress

Im using Yii createCommand QueryBuilder and constructing below insert query, below code works like charm (inserts 6000 records in 3 secs) but after sometime its speed becomes very slow.
My code:
$taskmodel = TaskModel::model()->findAll($cri); // filtering using some criteria
$now = new DateTime();
foreach( $taskmodel as $tsk ) {
$recall_date = $tsk['recall_date'] == "" ? "null" : '"'.$tsk['recall_date'].'"';
$recall_agent = $tsk['recall_agent_id'] == "" ? "null" : $tsk['recall_agent_id'];
$next_date = $tsk['next_action_date'] == "" ? "null" : '"'.$tsk['next_action_date'].'"';
$pc_color = $tsk['postcode_color'] == "" ? "null" : '"'.$tsk['postcode_color'].'"';
$cpc_id = $tsk['crm_campaign_post_code_id'] == "" ? "null" : $tsk['crm_campaign_post_code_id'];
$priority = $tsk['priority'] == "" ? 10 : $tsk['priority'];
$field1 = "null" ;
$field2 = "null"
$field3 = "null"
$field4 = "null" ;
$contact_timezone = $tsk['contact_timezone'] == "" ? "''" : '"'.$tsk['contact_timezone'].'"';
$sql[] = '('.$tsk['crm_task_id'].', '.$tsk['crm_campaign_id'].', "'.$tsk['crm_contact_id'].'", "'.$now->format('Y-m-d H:i:s').'", "'.$now->format('Y-m-d H:i:s').'
", '.$tsk['crm_filter_id'].', '.$tsk['current_status'].', '.$priority.', '.$recall_date.', '.$recall_agent.', '.$next_date.
', '.$pc_color.', '.$cpc_id.', '.$sort.', '.$field1.', '.$field2.', '.$field3.', '.$field4.', '.$contact_timezone.', '.$tsk['is_active'].')';
}
if(sizeof($sql) > 0){
$ins ='INSERT INTO crm_pending_task (crm_task_id, crm_campaign_id,crm_contact_id,created,updated,crm_filter_id,
current_status,priority,recall_date,recall_agent_id,next_action_date,postcode_color,crm_campaign_post_code_id,sort,
field1,field2,field3,field4,contact_timezone,is_active) VALUES '.implode(',', $sql);
Yii::app()->db->createCommand($ins)->execute();
}
i found something interesting, after inserting 50000 records it becomes slow !!! why is it so ???
How to improve insert query speed till it finishes all insertion ?
I think is because your request is taking too much memory and you are swapping.
To free some memory you shouldt try to enable Gc and launch it in your foreach (maybe not at each iteration)
gc_enable();
gc_collect_cycles();
Perhaps trying inserting smaller chunks into the database.
foreach( $taskmodel as $tsk ) {
$recall_date = $tsk['recall_date'] == "" ? "null" : '"'.$tsk['recall_date'].'"';
$recall_agent = $tsk['recall_agent_id'] == "" ? "null" : $tsk['recall_agent_id'];
$next_date = $tsk['next_action_date'] == "" ? "null" : '"'.$tsk['next_action_date'].'"';
$pc_color = $tsk['postcode_color'] == "" ? "null" : '"'.$tsk['postcode_color'].'"';
$cpc_id = $tsk['crm_campaign_post_code_id'] == "" ? "null" : $tsk['crm_campaign_post_code_id'];
$priority = $tsk['priority'] == "" ? 10 : $tsk['priority'];
$field1 = "null" ;
$field2 = "null"
$field3 = "null"
$field4 = "null" ;
$contact_timezone = $tsk['contact_timezone'] == "" ? "''" : '"'.$tsk['contact_timezone'].'"';
$sql[] = '('.$tsk['crm_task_id'].', '.$tsk['crm_campaign_id'].', "'.$tsk['crm_contact_id'].'", "'.$now->format('Y-m-d H:i:s').'", "'.$now->format('Y-m-d H:i:s').'
", '.$tsk['crm_filter_id'].', '.$tsk['current_status'].', '.$priority.', '.$recall_date.', '.$recall_agent.', '.$next_date.
', '.$pc_color.', '.$cpc_id.', '.$sort.', '.$field1.', '.$field2.', '.$field3.', '.$field4.', '.$contact_timezone.', '.$tsk['is_active'].')';
}
$recordCount = sizeof($sql);
$sliceSize = 250;
for($x = 0; $x < $recordCount; $x += $sliceSize) {
$ins = sprintf('
INSERT INTO
crm_pending_task
(
crm_task_id, crm_campaign_id, crm_contact_id, created,updated,
crm_filter_id, current_status, priority, recall_date, recall_agent_id,
next_action_date, postcode_color, crm_campaign_post_code_id, sort,
field1, field2, field3, field4, contact_timezone, is_active
)
VALUES
%s; ', implode(',', array_slice($sql, $x, $sliceSize));
Yii::app()->db->createCommand($ins)->execute();
}
}

Building WHERE clauses from multiple $_GET's

I am currently trying to write complex MySQL WHERE clauses that are generated from $_GET variables (which themselves come from select dropdowns). First, a bit of code so you know what I am talking about:
if(!isset($_GET['order'])){
$order= 'start asc';
} elseif ($_GET['order'] == "dateasc") {
$order= 'start asc';
} elseif ($_GET['order'] == "titleasc") {
$order= 'title asc';
} elseif ($_GET['order'] == "titledesc") {
$order= 'title desc';
};
if(!isset($_GET['cat'])){
$cat= '0';
} else {
$cat = $_GET['cat'];
};
if(!isset($_GET['loc'])){
$loc= '0';
} else {
$loc = $_GET['loc'];
};
if (isset($_GET['sd']) || isset($_GET['ed']) || isset($_GET['cat']) || isset($_GET['loc']) || isset($_GET['order']) ) {
$where = 'WHERE ';
if (isset($_GET['sd'])) {
$where .= "start = " . $_GET['sd'];
};
if (isset($_GET['ed'])) {
$where .= "AND end = " . $_GET['ed'];
};
if (isset($_GET['cat'])) {
$where .= "AND category = " . $_GET['cat'];
};
if (isset($_GET['loc'])) {
$where .= "AND location = " . $_GET['loc'];
};
};
$result = mysql_query("SELECT * FROM " . TABLE . $where . " ORDER BY " . $order);
Obviously this isn't working, otherwise I wouldn't be here. :) Basically, I have 4 variables that I want to conditionally use for sorting in my query: start date, and end date, a category, and a location. My problem is that all 4 of these may not always be used.. so given the above example, there might be a case where someone selects a category ($cat) but NOT a start date ($sd)... which means my WHERE clause would start off with 'AND', which is obviously invalid. So how do I build a query based off variables that may or may not be used?
I really feel like I am overthinking this, and I am afraid of writing 9000 lines of isset tests to account for every combination of $_GET variable usage. Surely there a simple way to build a WHERE clause from multiple $_GETs that may or may not be used every time..? I've tried Googling but can only find solutions that suggest using a framework for building complex queries and that just seems overly... clunky... for such a simple problem.
If you're just worried about having a where clause that starts with AND you can add 1=1 to account for no filters.
WHERE 1=1
Then, if you have any filters, it will look like this:
WHERE 1=1 AND col1=? AND col2=?
This may not be the cleanest solution, but it should be fairly simple to understand and implement.
if (isset($_GET['sd']) || isset($_GET['ed']) || isset($_GET['cat']) || isset($_GET['loc']) || isset($_GET['order']) ) {
$where = 'WHERE ';
if (isset($_GET['sd'])) {
if(strlen($where) > 6) {
$where .= " AND ";
}
$where .= "start = " . $_GET['sd'];
}
if (isset($_GET['ed'])) {
if(strlen($where) > 6) {
$where .= " AND ";
}
$where .= "end = " . $_GET['ed'];
}
if (isset($_GET['cat'])) {
if(strlen($where) > 6) {
$where .= " AND ";
}
$where .= "category = " . $_GET['cat'];
}
if (isset($_GET['loc'])) {
if(strlen($where) > 6) {
$where .= " AND ";
}
$where .= "location = " . $_GET['loc'];
}
}

PHP script error Notice: Undefined variable

I am writing a PHP script for advanced searching but an error occurred. Please help
Code:
$key = $_GET['key'];
$auth = $_GET['auth'];
$lang = $_GET['lang'];
$pub = $_GET['pub'];
if(isset($key) OR isset($auth) OR isset($lang) OR isset($pub))
{
if ($key != NULL){$keyword = "AND (native_name LIKE '%".$key."%' OR unique_name LIKE '%".$key."%')";}
if ($auth != 0) {$auther = "AND auth_id=".$auth."";}
if ($lang != 0) {$language = "AND lang_id=".$lang."";}
if ($pub != 0) {$publisher = "AND pub_id=".$pub."";}
$search_query = "SELECT native_name from books WHERE status=1 ".$keyword." ".$auther." ".$language." ".$publisher."";
print $search_query;
}
Error:
Notice: Undefined variable: keyword in FILE_PATH on line 90
Notice: Undefined variable: auther in FILE_PATH on line 90
Notice: Undefined variable: language in FILE_PATH on line 90
Notice: Undefined variable: publisher in FILE_PATH on line 90
If you are creating variables through if statements then there is a likelihood that these variables won't be created.
There are a couple of different options in your case.
1, Use Ternary syntax
$keyword = $key != NULL ? "AND (native_name LIKE '%".$key."%' OR unique_name LIKE '%".$key."%')" : "";
$author = $auth !=0 ? "AND auth_id=".$auth : "";
$language = $lang !=0 ? "AND lang_id=".$lang : "";
$publisher = $pub !=0 ? "AND pub_id=".$pub : "";
2, Predefine your variables
$keyword = "";
$author = "";
$language = "";
$publisher = "";
if ($key != NULL){$keyword = "AND (native_name LIKE '%".$key."%' OR unique_name LIKE '%".$key."%')";}
if ($auth != 0) {$auther = "AND auth_id=".$auth."";}
if ($lang != 0) {$language = "AND lang_id=".$lang."";}
if ($pub != 0) {$publisher = "AND pub_id=".$pub."";}
$keyword/$auther/etc.. only get assigned if the corresponding value in _POST is set. If no data is passed in, $key/$auth/etc... will be empty strings or null, which will be equal to 0/null. Try:
if ($key != null) {
$keyword = ...;
} else {
$keyword = some default value;
}
and similarly for the other ones.

Which function should I use for testing if a var is set or not?

I'm sometimes confused to using which one of them,
say I have a function called getmember($id)
function getmember($id)
{
// now this is the confusing part
// how do i test if a $id was set or not set?
//solution 1
if(empty($id))
{
return false;
}
// solution 2
if(isset($id))
{
return false;
}
}
That's sometimes not clear to me, sometimes if a parameter in a function is set like function($var="")
Then I do
if($var ==="")
{
return false;
}
What should I use the next time isset ? empty ? or ===''?
Here you go, a complete breakdown of what works and when:
<?
echo "<pre>";
$nullVariable = null;
echo 'is_null($nullVariable) = ' . (is_null($nullVariable) ? 'TRUE' : 'FALSE') . "\n";
echo 'empty($nullVariable) = ' . (empty($nullVariable) ? 'TRUE' : 'FALSE') . "\n";
echo 'isset($nullVariable) = ' . (isset($nullVariable) ? 'TRUE' : 'FALSE') . "\n";
echo '(bool)$nullVariable = ' . ($nullVariable ? 'TRUE' : 'FALSE') . "\n\n";
$emptyString = '';
echo 'is_null($emptyString) = ' . (is_null($emptyString) ? 'TRUE' : 'FALSE') . "\n";
echo 'empty($emptyString) = ' . (empty($emptyString) ? 'TRUE' : 'FALSE') . "\n";
echo 'isset($emptyString) = ' . (isset($emptyString) ? 'TRUE' : 'FALSE') . "\n";
echo '(bool)$emptyString = ' . ($emptyString ? 'TRUE' : 'FALSE') . "\n\n";
//note that the only one that won't throw an error is isset()
echo 'is_null($nonexistantVariable) = ' . (#is_null($nonexistantVariable) ? 'TRUE' : 'FALSE') . "\n";
echo 'empty($nonexistantVariable) = ' . (#empty($nonexistantVariable) ? 'TRUE' : 'FALSE') . "\n";
echo 'isset($nonexistantVariable) = ' . (isset($nonexistantVariable) ? 'TRUE' : 'FALSE') . "\n";
echo '(bool)$nonexistantVariable = ' . (#$nonexistantVariable ? 'TRUE' : 'FALSE') . "\n\n";
?>
THE OUTPUT:
is_null($nullVariable) = TRUE
empty($nullVariable) = TRUE
isset($nullVariable) = FALSE
(bool)$nullVariable = FALSE
is_null($emptyString) = FALSE
empty($emptyString) = TRUE
isset($emptyString) = TRUE
(bool)$emptyString = FALSE
is_null($nonexistantVariable) = TRUE
empty($nonexistantVariable) = TRUE
isset($nonexistantVariable) = FALSE
(bool)$nonexistantVariable = FALSE
When I show (bool)$variable above, that is how you could use it in a conditional. For example, to check if a variable is null or empty, you could do:
if (!$variable)
echo "variable is either null or empty!";
But it's best to use a function since it's a little more readable. But it's your choice.
Also, check the PHP type comparison table. It's basically what I just did above, except much more.
If you simply want to know if a variable is defined, use isset()
If you want to see if it's been initialized, use is_null()
If you want to compare it's value to something else, use ==
Not the same:
isset: Determine if a variable is set and is not NULL
http://ch.php.net/manual/en/function.isset.php
empty: Determine whether a variable is empty
http://ch.php.net/manual/en/function.empty.php
$a===$b: TRUE if $a is equal to $b, and they are of the same type.
http://ch.php.net/manual/en/language.operators.comparison.php

Categories