Related
This issue has been causing me a headache over the last month. What this code does is take a list of client sites and measures it against a list of contractor addresses. Each client site is a key to an array with 5 objects (5 nearest contractors) as its values. The problem happens when I give it more than ~30 client addresses to match it against my database (205 vendors) and find the closest 5 vendors for each site, PHP injects bogus characters(as pictured). Also, when these characters show up(they show up towards the end of the output), the array never finishes as it stops before the closing bracket or a few lines before that, this happens both before I use json_encode and after.
The bogus characters change around but they're usually :
�
What I've tried:
Encoding everything to UTF-8 (This includes all values in the code as well as in the file settings themselves)
Change my database from running off a CSV table to a MySQL table.
Used JsonSerializable for my objects.
Raising the memory limit in my php.ini.
Fiddling with the json_encode options
What I know:
The bogus characters are entered into the array itself, not after using json_encode().
Results are the same whether I encode to UTF-8 or not.
This didn't show up when I used json_encode for each client site separately (but was stuck not knowing how to append the json arrays into one large json array after the loop is done)
parseclientsite.php
<?php
$tmpName ="clientsitelist.xlsx";
require "vendor/autoload.php";
include("Libraries/SimpleXLSX.php");
include("database.php");
$xlsx = SimpleXLSX::parse($tmpName);
$xlsx = $xlsx->rows();
parseSiteFile($xlsx);
function parseSiteFile($siteArray){
$nomenclatureBuilding = ["Street Address", "Site Address", "Address", "Site", "street address", "Street address"];
$nomenclaturePostcode = ["Postcode", "Post code", "post code", "postcode", "Post Code"];
$n = 0;
$b = false;
$correctHeaders = $correctPairing = [];
$correctList = array();
foreach ($siteArray as $key => $value) {
if (!$b) {
//first row header
for ($i = 0; $i <= count($value) - 1; $i++) {
$correctHeaders[$value[$i]] = "";
if (in_array($value[$i], $nomenclatureBuilding,)) {
$streetColumn = trim($value[$i]);
}
if (in_array($value[$i], $nomenclaturePostcode,)) {
$postcodeColumn = trim($value[$i]);
}
}
$b = true;
continue;
}
foreach ($correctHeaders as $key2 => $value2) {
$correctPairing[$key2] = trim($value[$n]) ?? null;
$n++;
}
$n = 0;
if (isset($postcodeColumn)) {
$siteAddress = trim($correctPairing[$streetColumn] . " " . $correctPairing[$postcodeColumn] . ", Australia");
array_push($correctList, createSingleQuery($siteAddress));
} else {
$siteAddress = trim($correctPairing[$streetColumn] . ", Australia");
array_push($correctList, createSingleQuery($siteAddress));
}
}
echo json_encode($correctList, JSON_PARTIAL_OUTPUT_ON_ERROR| JSON_PRETTY_PRINT | JSON_UNESCAPED_LINE_TERMINATORS| JSON_INVALID_UTF8_IGNORE);
}
function createSingleQuery($siteAddress)
{
$httpClient = new Client();
$provider = new GoogleMaps($httpClient, null, 'key');
$geocoder = new StatefulGeocoder($provider, 'en');
$siteCoordinates = $geocoder->geocodeQuery(GeocodeQuery::create($siteAddress));
if ($siteCoordinates->isEmpty() == 1) {
$latitude1 = "0";
$longitude1 = "0";
} else {
$latitude1 = trim($siteCoordinates->get(0)->getCoordinates()->getLatitude());
$longitude1 = trim($siteCoordinates->get(0)->getCoordinates()->getLongitude());
}
$correctList[$siteAddress] = readDatabase($latitude1, $longitude1);
return $correctList;
}
?>
database.php
include("classes.php");
if (isset($_GET['location'])) {
$query = $_GET['location'];
singleQuery($query);
}
function readDatabase($latitude1, $longitude1){
$dbhost = 'localhost';
$dbuser = 'user';
$dbpass = 'password';
$conn = mysqli_connect($dbhost, $dbuser, $dbpass, 'vendors', 0,'/var/run/mysqld/mysqld.sock');
$sql = "SELECT BHS_Rate_Ex_GST, After_Hours_Rate_Ex_GST, Phone_Number, Company_Name, Street_Address, Charges_KM_Rate, Latitude, Longitude FROM mytable";
$result = $conn->query($sql);
$measurement = array();
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$vendorSite = array();
array_push($vendorSite, $row["Latitude"], $row["Longitude"]);
array_push($measurement, new Vendor(
$row["BHS_Rate_Ex_GST"],$row["After_Hours_Rate_Ex_GST"], $row["Phone_Number"], $row["Company_Name"], $row["Street_Address"], compareDistance($latitude1, $longitude1, $vendorSite), $row["Charges_KM_Rate"]));
}
usort($measurement,function($first,$second){
return $first->Distance <=> $second->Distance;
});
return $measurement = array_slice($measurement,0, 5);
}
$conn->close();
}
function compareDistance($latitude1, $longitude1, $vendorSite)
{
$earthMeanRadius = 6371;
$latitude2 = floatval($vendorSite[0]);
$longitude2 = floatval($vendorSite[1]);
$dLat = deg2rad($latitude2 - $latitude1);
$dLon = deg2rad($longitude2 - $longitude1);
$a = sin($dLat / 2) * sin($dLat / 2) + cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * sin($dLon / 2) * sin($dLon / 2);
$c = 2 * asin(sqrt($a));
return round(($earthMeanRadius * $c), 2);
}
classes.php
class Vendor {
public function __construct($Cost, $Ah, $Phone, $Name, $Address, $Distance, $Travel) {
$this->Cost = $Cost;
$this->Ah = $Ah;
$this->Phone = $Phone;
$this->Name = $Name;
$this->Address = $Address;
$this->Distance = $Distance;
$this->Travel = $Travel;
}
public function __toString() {
return $this->Cost . ' ' . $this->Ah . ' ' .$this->Phone . ' ' . $this->Name
. ' ' . $this->Address . ' ' . $this->Distance. ' ' . $this->Travel;
}
}
Code was OK, PHPstorm's server was the culprit.
I want to make a code user id with my style, but i confuse to make it in Yii 2.
Can you help me, how write the query like this code below in Yii 2.
This is my code:
$sql = "select * from `$tbadmin` order by `kode_admin` desc";
$q = mysql_query($sql);
$jum = mysql_num_rows($q);
$kd = "ADM";
if ($jum > 0) {
$d = mysql_fetch_array($q);
$idmax = $d["kode_admin"];
$urut = substr($idmax, 3, 2) + 1; //01
if ($urut < 10) {
$idmax = "$kd" . "0" . $urut;
} else {
$idmax = "$kd" . $urut;
}
} else {
$idmax = "$kd" . "01";
}
$kode_admin = $idmax;
$model = Admin::find()->orderBy(['kode_admin DESC'])->all();
foreach($model as $m) {
$m->kode_admin = $this->createKode();
$m->save();
}
Admin is the model for tbadmin table, and createKode could be a function in your controller.
If your are creating a new Admin:
$model = new Admin();
$model->kode_admin = $this->createKode();
$model->save();
$model = AdminModelName::find()->orderBy('kode_admin DESC')->asArray()->all();
foreach($model as $m) {
$m->kode_admin = $this->createKode();
$m->save();
}
create model with Gii Tools
$model = \app\models\tbadmin::find()
->select()
->orderby(['kode_admin => SORT_DESC',])
->all();
This question already has answers here:
mysqli_stmt::bind_result(): Number of bind variables doesn't match number of fields in prepared statement
(2 answers)
Closed 1 year ago.
For some reason I keep getting this error when attempting to run prepared query with mysqli
mysqli_stmt::bind_result(): Number of bind variables doesn't match
number of fields in prepared statement
This db class works fine until I try to use a query with LEFT OUTER JOIN
I'm wondering if anyone knows why? I'll post the query, schema, etc.. below.
NOTE: I saw one question on here that suggested I specifically spell out all the field names I want to select, rather than use '*'(star). There are A LOT of fields involved and I spent almost an hour typing them all out. When I tested, it didn't change anything. I have omitted that and returned to using star just in case anyone was going to suggest I type them all out. Already tried. Doesn't help.
ALSO: This query works fine if I put it straight into phpMyAdmin, so it's a working query. Just throwing an error when trying to bind the result for some reason. Even if I remove the multiple joins and just have one left join it still throws the error about not having the correct parameter count. I don't get it.
Query Output by PHP
SELECT * FROM `SlipMaster`
left outer join `SlipMain`
on `SlipMaster`.`slipCode` = `SlipMain`.`slipCode`
left outer join `ContractMain`
on `SlipMain`.`slipContractId` = `ContractMain`.`id`
left outer join `ClientMain`
on `SlipMain`.`slipClientId` = `ClientMain`.`id`
left outer join `PaymentMain`
on `ContractMain`.`contractPaymentId` = `PaymentMain`.`id`
left outer join `VesselMain`
on `SlipMain`.`slipVesselId` = `VesselMain`.`id`
WHERE 1 = ?
PHP CODE USING MYSQLI DB CLASS
$from = '
`SlipMaster`
left outer join `SlipMain`
on `SlipMaster`.`slipCode` = `SlipMain`.`slipCode`
left outer join `ContractMain`
on `SlipMain`.`slipContractId` = `ContractMain`.`id`
left outer join `ClientMain`
on `SlipMain`.`slipClientId` = `ClientMain`.`id`
left outer join `PaymentMain`
on `ContractMain`.`contractPaymentId` = `PaymentMain`.`id`
left outer join `VesselMain`
on `SlipMain`.`slipVesselId` = `VesselMain`.`id`';
$dbi->new_query();
$dbi->add_param('i', '1');
$dbi->select($from, '*', '1=?');
PHP MYSQLI DB CLASS
<?php
class mysqliObject {
public $user = "";
public $pass = "";
public $name = "";
public $host = "";
public $_db;
public $_config;
public $MYSQLI_LINK = FALSE;
public $rows = FALSE;
public $last_error = FALSE;
public $last_query = FALSE;
public $result = FALSE;
public $last_id = FALSE;
public $paramTypeArray = [];
public $paramBindArray = [];
public function __construct() {
}
public function __destruct() {
$this->close();
}
public function connect() {
$this->host = $this->_config->get('DBHOST');
$this->name = $this->_config->get('DBNAME');
$this->user = $this->_config->get('DBUSER');
$this->pass = $this->_config->get('DBPASS');
$this->MYSQLI_LINK = new mysqli($this->host, $this->user, $this->pass, $this->name);
}
public function setDatabase($databaseConnection) {
$this->_db = $databaseConnection;
}
public function setConfig($config) {
$this->_config = $config;
}
public function close() {
#mysqli_close($this->MYSQLI_LINK);
}
public function get_hash($p) {
return password_hash($p, PASSWORD_BCRYPT, array("cost" => 10));
}
public function check_password($p, $h) {
return (password_verify($p, $h)) ? true : false;
}
public function get_rndkey($length=32) {
$random_string="";
while(strlen($random_string)<$length && $length > 0) {
$randnum = mt_rand(0,61);
$random_string .= ($randnum < 10) ?
chr($randnum+48) : ($randnum < 36 ?
chr($randnum+55) : $randnum+61);
}
return $random_string;
}
public function escape($value) {
return mysqli_real_escape_string($this->MYSQLI_LINK, $value);
}
public function get_lastid() {
return $this->MYSQLI_LINK->insert_id;
}
public function new_query() {
$this->paramTypeArray = Array();
$this->paramBindArray = Array();
}
public function add_param($t, $d) {
$this->paramTypeArray[] = $t;
$this->paramBindArray[] = $d;
}
// Shortcut for Select Method
public function s($t,$x, $d, $w) {
$this->new_query();
foreach($d as $v) {
$this->add_param($v['t'], $v['v']);
}
return $this->select($t, $x, $w) ? $this->result : false;
}
public function select($t, $d, $c) {
/* Types: s = string, i = integer, d = double, b = blob */
$a_params = array();
$param_type = '';
$n = count($this->paramTypeArray);
for($i = 0; $i < $n; $i++) {
$param_type .= $this->paramTypeArray[$i];
}
$a_params[] = & $param_type;
for($i = 0; $i < $n; $i++) {
$a_bind_params[] = $this->paramBindArray[$i];
}
for($i = 0; $i < $n; $i++) {
$a_params[] = & $a_bind_params[$i];
}
$q = 'SELECT '.$d.' FROM '.$t.' WHERE '.$c;
$s = $this->MYSQLI_LINK->prepare($q);
if($s === false) {
trigger_error('Wrong SQL: ' . $q . ' Error: ' . $this->MYSQLI_LINK->errno . ' ' . $this->MYSQLI_LINK->error, E_USER_ERROR);
}
call_user_func_array(array($s, 'bind_param'), $a_params);
$s->execute();
$meta = $s->result_metadata();
while ($field = $meta->fetch_field()) {
$var = $field->name;
$$var = null;
$fields[$var] = &$$var;
}
call_user_func_array(array($s,'bind_result'),$fields);
$i = 0;
while ($s->fetch()) {
$results[$i] = [];
foreach($fields as $k => $v) {
$results[$i][$k] = $v;
}
$i++;
}
$s->close();
$this->last_query = $q;
if (count($results) > 0) {
$this->result = $results;
return TRUE;
} else {
$this->last_error = mysqli_error($this->MYSQLI_LINK);
return FALSE;
}
return FALSE;
}
public function delete($t, $c) {
$a_params = array();
$param_type = '';
$n = count($this->paramTypeArray);
for($i = 0; $i < $n; $i++) {
$param_type .= $this->paramTypeArray[$i];
}
$a_params[] = & $param_type;
for($i = 0; $i < $n; $i++) {
$a_bind_params[] = $this->paramBindArray[$i];
}
for($i = 0; $i < $n; $i++) {
$a_params[] = & $a_bind_params[$i];
}
$q = "delete from ".$t." where ".$c;
$s = $this->MYSQLI_LINK->prepare($q);
$this->last_query = $q;
if($s === false) {
trigger_error('Wrong SQL: ' . $q . ' Error: ' . $this->MYSQLI_LINK->errno . ' ' . $this->MYSQLI_LINK->error, E_USER_ERROR);
}
call_user_func_array(array($s, 'bind_param'), $a_params);
$s->execute();
$count = $s->affected_rows;
$s->close();
if ($count > 0) {
$this->rows = $count;
return TRUE;
} else {
$this->last_error = mysqli_error($this->MYSQLI_LINK);
return FALSE;
}
}
public function insert($t, $d) {
$a_params = array();
$param_type = '';
$n = count($this->paramTypeArray);
for($i = 0; $i < $n; $i++) {
$param_type .= $this->paramTypeArray[$i];
}
$a_params[] = & $param_type;
for($i = 0; $i < $n; $i++) {
$a_bind_params[] = $this->paramBindArray[$i];
}
for($i = 0; $i < $n; $i++) {
$a_params[] = & $a_bind_params[$i];
}
$query_cols = 'insert into '.$t.' (';
$query_vals = 'values (';
while (list($key, $value) = each($d)) {
$query_cols .= $value . ', ';
$query_vals .= '?, ';
}
$query_cols = substr($query_cols, 0, strlen($query_cols) - 2);
$query_vals = substr($query_vals, 0, strlen($query_vals) - 2);
$q = $query_cols . ') ' . $query_vals . ')';
$this->last_query = $q;
$s = $this->MYSQLI_LINK->prepare($q);
if($s === false) {
trigger_error('Wrong SQL: ' . $q . ' Error: ' . $this->MYSQLI_LINK->errno . ' ' . $this->MYSQLI_LINK->error, E_USER_ERROR);
}
call_user_func_array(array($s, 'bind_param'), $a_params);
$s->execute();
$count = $s->affected_rows;
$this->last_id = $s->insert_id;
$s->close();
if ($count > 0) {
$this->rows = $count;
return TRUE;
} else {
$this->last_error = mysqli_error($this->MYSQLI_LINK);
return FALSE;
}
}
public function update($t, $d, $c) {
$a_params = array();
$param_type = '';
$n = count($this->paramTypeArray);
for($i = 0; $i < $n; $i++) {
$param_type .= $this->paramTypeArray[$i];
}
$a_params[] = & $param_type;
for($i = 0; $i < $n; $i++) {
$a_bind_params[] = $this->paramBindArray[$i];
}
for($i = 0; $i < $n; $i++) {
$a_params[] = & $a_bind_params[$i];
}
$q = 'update ' . $t . ' set ';
while (list($key, $value) = each($d)) {
$q .= $value . ' = ?, ';
}
//strip comma off end of variable
$q = substr($q, 0, strlen($q) - 2);
$q .= ' where ' . $c;
$this->last_query = $q;
$s = $this->MYSQLI_LINK->prepare($q);
if($s === false) {
trigger_error('Wrong SQL: ' . $q . ' Error: ' . $this->MYSQLI_LINK->errno . ' ' . $this->MYSQLI_LINK->error, E_USER_ERROR);
}
call_user_func_array(array($s, 'bind_param'), $a_params);
$s->execute();
$count = $s->affected_rows;
$s->close();
if ($count > 0) {
$this->rows = $count;
return TRUE;
} else {
$this->last_error = mysqli_error($this->MYSQLI_LINK);
return FALSE;
}
}
} // End Class
Simplified Schema
NOTE: Let me know if you need me to post a more complete schema. This just shows the fields that are linking the joins. All fields are INT(255) unique, id fields are INT(255) AI PRIMARY
SlipMaster links to SlipMain via slipCode, all others link foreign key
to Primary id
SlipMaster (id, slipCode)
SlipMain (id, slipCode, slipContractId, slipClientId, slipVesselId)
ContractMain (id, contractPaymentId)
ClientMain (id)
PaymentMain (id)
VesselMain (id)
* is all the fields in all the tables you are JOINing together. This includes duplicates, such as slipCode, which exists at least twice.
Plan A: Spell out the fields that you really want. This will make it easier to count them and know how many to "bind". And it will make it clear what order to bind them in.
Plan B: Don't use bind_result; simply fetch the result into an array or hash.
Plan C: Do both. (I prefer this.)
#Notorious, I think the answer to your problem is not the sql but to the bind_result() function that you are using.
Explaining furthur, the bind_result() function is used to assign retrieved data from the database to variables. So the number of fields selected (returned from the database) must be equal to the number of binded results.
For instance,
If I selected the firstname and the lastname fields from the database I must use
bind_result($firstname, $lastname);
So as you can see the number of variables in the bind_result() is equal to the number of fields selected.
For your case you are selecting everything from the first db to second to third ..blablabla till the last db. So make sure the number of fields assigned to the the bind_result() function is equal to the number of all the fields returned. That is the sum of the total number of columns in all the databases.
So you got a lot of typing to do but at least its for the best.
Good luck and I hope it helped.
I´m pretty much entirely new to PHP, so please bear with me.
I´m trying to build a website running on a cms called Core. I'm trying to make it so that the previous/next buttons cycle through tags rather than entries. Tags are stored in a database as core_tags. Each tag has it own tag_id, which is a number. I've tried changing the excisting code for thep previous/next buttons, but it keeps giving me 'Warning: mysql_fetch_array() expects parameter 1 to be resource, null given in /home/core/functions/get_entry.php on line 50'.'
Any help would be greatly appreciated.
Get_entry.php:
<?php
$b = $_SERVER['REQUEST_URI'];
if($entry) {
$b = substr($b,0,strrpos($b,"/")) . "/core/";
$id = $entry;
$isPerma = true;
} else {
$b = substr($b,0,mb_strrpos($b,"/core/")+6);
$id = $_REQUEST["id"];
}
$root = $_SERVER['DOCUMENT_ROOT'] . $b;
$http = "http://" . $_SERVER['HTTP_HOST'] . substr($b,0,strlen($b)-5);
require_once($root . "user/configuration.php");
require_once($root . "themes/".$theme."/configuration.php");
require_once($root . "functions/session.php");
if(is_numeric($id)) {
$type = "entry";
} else {
$type = "page";
}
$id = secure($id);
if($type == "page") {
$data = mysql_query("SELECT p.* FROM core_pages p WHERE p.page_title = \"$id\"");
$page_clicks = 0;
while($p = mysql_fetch_array($data)) {
$url = $p["page_url"];
$path = $root . "user/pages/" . $url;
$page_clicks = $p['hits']+1;
require($path);
}
mysql_query("UPDATE core_pages p SET
p.hits = $page_clicks
WHERE p.page_title = $id");
}
if($type == "entry") {
// queries the dbase
$data_tags = mysql_query("SELECT entry_id,entry_title FROM core_entries WHERE entry_show = 1 ORDER BY entry_position DESC") or die(mysql_error());
$navArr=array();
while($tmparray = mysql_fetch_array($data_entries,MYSQL_ASSOC)){
array_push($navArr,$tmparray['entry_id']);
}
function array_next_previous($array, $value) {
$index = array_search($value,$array);
//if user clicked to view the very first entry
if($value == reset($array)){
$return['prev'] = end($array);
$return['next'] = $array[$index + 1];
//if user clicked to view the very last entry
}else if($value == end($array)){
$return['prev'] = $array[$index - 1];
reset($array);
$return['next'] = current($array);
}else{
$return['next'] = $array[$index + 1];
$return['prev'] = $array[$index - 1];
}
return $return;
}
$data = mysql_query("SELECT e.* FROM core_entries e WHERE e.entry_id = $id AND e.entry_show = 1");
$entry_clicks = 0;
if(#mysql_num_rows($data) < 1) {
die("Invalid id, no entry to be shown");
}
while($e = mysql_fetch_array($data)) {
$nextPrevProject = array_next_previous($navArr,$id);
$entry_id = $e['entry_id'];
$entry_title = $e['entry_title'];
// DATE
$t = $e["entry_date"];
$y = substr($t,0,4);
$m = substr($t,5,2);
$d = substr($t,8,2);
$entry_date = date($date_format,mktime(0,0,0,$m,$d,$y));
$entry_text = $e['entry_text'];
$entry_extra1 = $e['entry_extra1'];
$entry_extra2 = $e['entry_extra2'];
$entry_client = $e['entry_client'];
$entry_position = $e['entry_position'];
$entry_hits = $e['hits']+1;
$entry_new = $e['entry_new'];
if($entry_new == 1) {
$isNew = true;
} else {
$isNew = false;
}
if($nice_permalinks) {
$entry_perma = "$http".$entry_id;
} else {
$entry_perma = "$http"."?entry=$entry_id";
}
$data_e2t = #mysql_query("SELECT e2t.tag_id FROM core_entry2tag e2t WHERE e2t.entry_id = $entry_id");
$tag_str = "";
while($e2t = #mysql_fetch_array($data_e2t)) {
$tag_id = $e2t["tag_id"];
$data_tags = #mysql_query("SELECT t.tag_text FROM core_tags t WHERE t.tag_id = $tag_id");
while($t = #mysql_fetch_array($data_tags)) {
$tag_text = $t["tag_text"];
$tag_str = $tag_str . "<a class=\"tag-link\" name=\"tag".$tag_id."\" href=\"#tag-"._encode($tag_text)."\">".$tag_text."</a>".$separator_tags;
}
}
$entry_tags = substr($tag_str,0,strlen($tag_str)-strlen($separator_tags));
$layout_path = $root . "user/uploads/" . treat_string($entry_title) . "/layout.php";
if(is_file($layout_path) && (#filesize($layout_path) > 0)) {
require($layout_path);
} else {
require($theme_path . "parts/entry.php");
}
}
mysql_query("UPDATE core_entries e SET
e.hits = $entry_hits
WHERE e.entry_id = $id");
}
if($isPerma) {
echo "<a class=\"index-link\" href=\"$http\">back to index</a>";
}
?>
You have not defined $data_entries, before using it here:
while($tmparray = mysql_fetch_array($data_entries,MYSQL_ASSOC)){
array_push($navArr,$tmparray['entry_id']);
}
That is why you get the very descriptive error message.
Did you mean to use $data_tags?
Use: "SELECT p.* FROM core_pages p WHERE p.page_title = '".$id."'
Note: mysql_connect is not sql-injection save. If you use mysql_connect, change to PDO.
$data_entries is not defined on line 50, then mysql_fetch_array return an exception of null value given.
Try to change $tmparray = mysql_fetch_array($data_entries,MYSQL_ASSOC) to $tmparray = mysql_fetch_array($data_tags,MYSQL_ASSOC).
Hope this help!
I am trying to get the integrated search toolbars working on my page, however I am not having any luck. The regular search function is working for me, but whenever I type anything into the integrated toolbars, it returns 0 results.
Here is my jquery:
$("#parts_table").jqGrid({
url:'testparts2.php',
datatype: "json",
colNames:['Part ID','Name', 'Description', 'Weight'],
colModel:[
{name:'part_ID',index:'part_ID', search: true, stype:'text', width:55},
{name:'part_name',index:'part_name', width:90},
{name:'part_desc',index:'part_desc', width:100},
{name:'part_weight',index:'part_weight', width:80, align:"right"},
],
rowNum:30,
rowList:[10,20,30],
pager: '#pager2',
sortname: 'part_ID',
viewrecords: true,
sortorder: "asc",
caption:"Parts in Database",
width: '800',
height: '300',
});
$("#parts_table").jqGrid('navGrid','#pager2',{edit:false,add:false,del:false});
$("#parts_table").jqGrid('filterToolbar',{stringResult: false,searchOnEnter : false, defaultSearch: 'cn', ignoreCase: true});
and here is my PHP code:
<?php
include "begin.php";
$page = $_REQUEST['page']; // get the requested page
$limit = $_REQUEST['rows']; // get how many rows we want to have into the grid
$sidx = $_REQUEST['sidx']; // get index row - i.e. user click to sort
$sord = $_REQUEST['sord']; // get the direction
if(!$sidx) $sidx =1;
//array to translate the search type
$ops = array(
'eq'=>'=', //equal
'ne'=>'<>',//not equal
'lt'=>'<', //less than
'le'=>'<=',//less than or equal
'gt'=>'>', //greater than
'ge'=>'>=',//greater than or equal
'bw'=>'LIKE', //begins with
'bn'=>'NOT LIKE', //doesn't begin with
'in'=>'LIKE', //is in
'ni'=>'NOT LIKE', //is not in
'ew'=>'LIKE', //ends with
'en'=>'NOT LIKE', //doesn't end with
'cn'=>'LIKE', // contains
'nc'=>'NOT LIKE' //doesn't contain
);
function getWhereClause($col, $oper, $val){
global $ops;
if($oper == 'bw' || $oper == 'bn') $val .= '%';
if($oper == 'ew' || $oper == 'en' ) $val = '%'.$val;
if($oper == 'cn' || $oper == 'nc' || $oper == 'in' || $oper == 'ni') $val = '%'.$val.'%';
return " WHERE $col {$ops[$oper]} '$val' ";
}
$where = ""; //if there is no search request sent by jqgrid, $where should be empty
$searchField = isset($_GET['searchField']) ? $_GET['searchField'] : false;
$searchOper = isset($_GET['searchOper']) ? $_GET['searchOper']: false;
$searchString = isset($_GET['searchString']) ? $_GET['searchString'] : false;
if ($_GET['_search'] == 'true') {
$where = getWhereClause($searchField,$searchOper,$searchString);
}
$totalrows = isset($_REQUEST['totalrows']) ? $_REQUEST['totalrows']: false;
if($totalrows) {
$limit = $totalrows;
}
$result = mysql_query("SELECT COUNT(*) AS count FROM parts");
$row = mysql_fetch_array($result,MYSQL_ASSOC);
$count = $row['count'];
if( $count >0 ) {
$total_pages = ceil($count/$limit);
} else {
$total_pages = 0;
}
if ($page > $total_pages) $page=$total_pages;
if ($limit<0) $limit = 0;
$start = $limit*$page - $limit; // do not put $limit*($page - 1)
if ($start<0) $start = 0;
$SQL = "SELECT * FROM parts ".$where." ORDER BY $sidx $sord LIMIT $start , $limit";
$result = mysql_query( $SQL ) or die("Couldn't execute query.".mysql_error());
$response->page = $page;
$response->total = $total_pages;
$response->records = $count;
$i=0;
while($row = mysql_fetch_array($result,MYSQL_ASSOC)) {
$response->rows[$i]['part_ID']=$row[part_ID];
$response->rows[$i]['cell']=array($row[part_ID],$row[part_name],$row[part_desc],$row[part_weight]);
$i++;
}
echo json_encode($response);
?>
It took me hours of searching to find a PHP example that worked for regular searching (see above), however it doesn't seem to work for the toolbar searching. Can anyone help? Thanks
edit: Here is code from jqGrid's demo folder for using this search, but it appears to be full of errors and I have no idea how to use it for my case. I don't need to specify data type for the searches (they are all varchars, so strings will work fine)..so I think that I can strip out the switch/case part for value conversion. I think I just need to change my original code to use $_REQUEST['filters'] and a foreach loop to build the query, but I'm not that great with PHP so any help is appreciated.
demo code:
$wh = "";
$searchOn = Strip($_REQUEST['_search']);
if($searchOn=='true') {
$searchstr = Strip($_REQUEST['filters']);
$wh= constructWhere($searchstr);
//echo $wh;
}
function constructWhere($s){
$qwery = "";
//['eq','ne','lt','le','gt','ge','bw','bn','in','ni','ew','en','cn','nc']
$qopers = array(
'eq'=>" = ",
'ne'=>" <> ",
'lt'=>" < ",
'le'=>" <= ",
'gt'=>" > ",
'ge'=>" >= ",
'bw'=>" LIKE ",
'bn'=>" NOT LIKE ",
'in'=>" IN ",
'ni'=>" NOT IN ",
'ew'=>" LIKE ",
'en'=>" NOT LIKE ",
'cn'=>" LIKE " ,
'nc'=>" NOT LIKE " );
if ($s) {
$jsona = json_decode($s,true);
if(is_array($jsona)){
$gopr = $jsona['groupOp'];
$rules = $jsona['rules'];
$i =0;
foreach($rules as $key=>$val) {
$field = $val['field'];
$op = $val['op'];
$v = $val['data'];
if($v && $op) {
$i++;
// ToSql in this case is absolutley needed
$v = ToSql($field,$op,$v);
if ($i == 1) $qwery = " AND ";
else $qwery .= " " .$gopr." ";
switch ($op) {
// in need other thing
case 'in' :
case 'ni' :
$qwery .= $field.$qopers[$op]." (".$v.")";
break;
default:
$qwery .= $field.$qopers[$op].$v;
}
}
}
}
}
return $qwery;
}
function ToSql ($field, $oper, $val) {
// we need here more advanced checking using the type of the field - i.e. integer, string, float
switch ($field) {
case 'id':
return intval($val);
break;
case 'amount':
case 'tax':
case 'total':
return floatval($val);
break;
default :
//mysql_real_escape_string is better
if($oper=='bw' || $oper=='bn') return "'" . addslashes($val) . "%'";
else if ($oper=='ew' || $oper=='en') return "'%" . addcslashes($val) . "'";
else if ($oper=='cn' || $oper=='nc') return "'%" . addslashes($val) . "%'";
else return "'" . addslashes($val) . "'";
}
}
$result = mysql_query("SELECT COUNT(*) AS count FROM invheader a, clients b WHERE a.client_id=b.client_id".$wh);
$row = mysql_fetch_array($result,MYSQL_ASSOC);
$count = $row['count'];
if( $count >0 ) {
$total_pages = ceil($count/$limit);
} else {
$total_pages = 0;
}
if ($page > $total_pages) $page=$total_pages;
$start = $limit*$page - $limit; // do not put $limit*($page - 1)
if ($start<0) $start = 0;
$SQL = "SELECT a.id, a.invdate, b.name, a.amount,a.tax,a.total,a.note FROM invheader a, clients b WHERE a.client_id=b.client_id".$wh." ORDER BY ".$sidx." ".$sord. " LIMIT ".$start." , ".$limit;
$result = mysql_query( $SQL ) or die("Could not execute query.".mysql_error());
$responce->page = $page;
$responce->total = $total_pages;
$responce->records = $count;
$i=0;
while($row = mysql_fetch_array($result,MYSQL_ASSOC)) {
$responce->rows[$i]['id']=$row[id];
$responce->rows[$i]['cell']=array($row[id],$row[invdate],$row[name],$row[amount],$row[tax],$row[total],$row[note]);
$i++;
}
//echo $json->encode($responce); // coment if php 5
echo json_encode($responce);
I actually just had this same problem myself yesterday. You are correct, you need to bring in the filters using $_REQUEST['filters'] and then break it up so that you can use each piece.
First, you are going to need to set stringResult: true in your jQuery file where you initialize the FilterToolbar.
Here is the code that PHP will use to bring in, and break up the filters object:
// Gets the 'filters' object from JSON
$filterResultsJSON = json_decode($_REQUEST['filters']);
// Converts the 'filters' object into a workable Array
$filterArray = get_object_vars($filterResultsJSON);
Now that you have $filterArray containing the contents of the filters object, you can now break up the rules object which is contained inside. Basically, there is another array inside the $filterArray which contains the search details if the user tries performing this search across multiple columns in their table - it's called rules.
Here is how I break up the rules object and perform a SELECT query based on the user's input:
// Begin the select statement by selecting cols from tbl
$sql = 'select '.implode(',',$crudColumns).' from '.$crudTableName;
// Init counter to 0
$counter = 0;
// Loop through the $filterArray until we process each 'rule' array inside
while($counter < count($filterArray['rules']))
{
// Convert the each 'rules' object into a workable Array
$filterRules = get_object_vars($filterArray['rules'][$counter]);
// If this is the first pass, start with the WHERE clause
if($counter == 0){
$sql .= ' WHERE ' . $filterRules['field'] . ' LIKE "%' . $filterRules['data'] . '%"';
}
// If this is the second or > pass, use AND
else {
$sql .= ' AND ' . $filterRules['field'] . ' LIKE "%' . $filterRules['data'] . '%"';
}
$counter++;
}
// Finish off the select statement
$sql .= ' ORDER BY ' . $postConfig['sortColumn'] . ' ' . $postConfig['sortOrder'];
$sql .= ' LIMIT '.$intStart.','.$intLimit;
/* run the query */
$result = mysql_query( $sql )
I'm sure you'll have questions, so feel free to ask if you do!