codeigniter search - php

hello i have little problem
i want search in mysql by name
i have this code in search model
$this->db->limit($limit, $start);
$this->db->like("name",$by);
$res = $this->db->get('walls');
if ($res->num_rows() > 0)
return $res->result();
result for $by = "megan"; is working
but when $by = "megan fox"; is not working
in mysql name i have "megan fox";
I tried urldecode but to no avail.
i using codeigniter framework..
any ideas?

$this->db->limit($limit, $start);
$this->db->like("name",$by);
$res = $this->db->get('walls');
if ($res->num_rows() > 0)
return $res->result();
You might want to add BOTH,LEFT,RIGHT on your like() clause example
$this->db->like("name",$by,'BOTH'); // left and right wild card %name%
$this->db->like("name",$by,'LEFT'); // left wild card %name
$this->db->like("name",$by,'RIGHT'); // right wild card name%
You can read more at http://ellislab.com/codeigniter/user-guide/database/active_record.html

You can first split the $by variable into separate values with something like this:
$by = explode(" ", $by);
and then try to make the like clause like this
$this->db->like("name",$by[0]);
$this->db->or_like("name",$by[1]);
It will produce something like this
WHERE name LIKE '%megan%' OR name LIKE '%fox%'
This assumes that you always pass 2 variables to the $by, seperated by space.
You have to adjust it to make sure it works in every case, for example when there is only one variable passed to the $by you should do a check for it.
And please note that it will be fairly slower than splitting the name and the surname into two separate fields in the table and querying each of them for a specific name or surname. You should do this if you care for optimization.

Use urldecode function to solve this
Try this into your model
$by= urldecode($by);
$this->db->limit($limit, $start);
$this->db->like("name",$by);
$res = $this->db->get('walls');
if ($res->num_rows() > 0)
return $res->result();

Related

Where to add the like clause in php?

where can I put the like statement on this code? I would want to allow the user to search any documents that are similar to the entered text it would be document like '%$search%;
public function getDoc($param=''){
if($this->User->PrincipalType!="All")$where['tbl_document.PrincipalType']=$this->User->PrincipalType;
if(!isset($param['RecordID']) || $param['RecordID']==''){
$where['tbl_document.Status !=']='Removed';
$this->db->select('tbl_document.*,cr.FirstName,cr.MiddleName,cr.LastName,up.FirstName as UFName,up.MiddleName as UMName,up.LastName as ULName');
$this->db->from('tbl_document');
$this->db->join('tbl_user `cr`', 'tbl_document.CreatedBy = cr.ID','left');
$this->db->join('tbl_user `up`', 'tbl_document.UpdatedBy = up.ID','left');
if(isset($param['DocTrack']) && $param['DocTrack']!='') $where['tbl_document.ID']=$param['DocTrack'];
$this->db->where($where);
if(isset($param['DocTrack']) && $param['DocTrack']!='')$this->db->or_where('tbl_document.Title',$param['DocTrack']);
$this->db->order_by('DateCreated', 'desc');
$query = $this->db->get();
$return=$query->result();
}
Assuming you want to search for $param['DocTrack'] then you can use below two approaches for like query execution as below:
1. $this->db->like('tbl_document.Title','%'.$param['DocTrack'].'%')
2. $this->db->where("tbl_document.Title LIKE '%".$param['DocTrack']."%'");
Hope it helps you :)

where clause not working with like query

I have a search query and when I search all like keywords work properly the records are showing with the matched criteria, but the problem is that where clause in not working.
$position = $this->session->set_userdata('position', $this->input->post('position'));
$adress_all = explode(",", $this->session->userdata('address'));
$this->db->like('address', $adress_all[0]);
$this->db->or_like('game', $this->session->userdata('skills'));
$this->db->or_like('gender', $this->session->userdata('coach'));
$this->db->or_like('Positions', $this->session->userdata('position'));
$this->db->where('type', 'private');//all other type coaches is also showing up
$sql = $this->db->get('coach');
You need to use Grouping LIKE of codeigniter
$this->db->group_start();
$this->db->like('address', $adress_all[0]);
$this->db->or_like('game', $this->session->userdata('skills'));
$this->db->or_like('gender', $this->session->userdata('coach'));
$this->db->or_like('Positions', $this->session->userdata('position'));
$this->db->group_end();
$this->db->where('type', 'private');
$sql = $this->db->get('coach');
Hope this works(need to test on your DB)
See Doc
Try below things.
$this->db->where('type', 'private');//all other type coaches is also showing up
$this->db->where("(address LIKE '%". $adress_all[0]."%' OR game LIKE '%".$this->session->userdata('skills')."%' OR gender LIKE '%".$this->session->userdata('coach')."%' OR positions LIKE '%".$this->session->userdata('position')."%')",null,false);
$sql = $this->db->get('coach');

MySQL query that can handle missing characters

I'm trying to improve my MySQL query.
SELECT gamename
FROM giveaway
WHERE gamename LIKE '$query'
I got an input that consists of URL's that are formed like:
http://www.steamgifts.com/giveaway/l7Jlj/plain-sight
http://www.steamgifts.com/giveaway/okjzc/tex-murphy-martian-memorandum
http://www.steamgifts.com/giveaway/RqIqD/flyn
http://www.steamgifts.com/giveaway/FzJBC/penguins-arena-sednas-world
I take the game name from the URL and use this as input for a SQL query.
$query = "plain sight"
$query = "tex murphy martian memorandum"
$query = "flyn"
$query = "penguins arena sednas world"
Now in the database the matching name sometimes has more characters like : ' !, etc.
Example:
"Plain Sight"
"Tex Murphy: Martian Memorandum"
"Fly'N"
"Penguins Arena: Sedna's World!"
So when putting in the acquired name from the URL this doesn't produce results for the 2nd, 3rd and 4th example.
So what I did was use a % character.
$query = "plain%sight"
$query = "tex%murphy%martian%memorandum"
$query = "flyn"
$query = "penguins%arena%sednas%world"
This now gives result on the 1st and 2nd example.
.
On to my question:
My question is, how to better improve this so that also the 3rd and 4th ones work?
I'm thinking about adding extra % before and after each character:
$query = "%f%l%y%n%"
$query = "%p%e%n%g%u%i%n%s%a%r%e%n%a%s%e%d%n%a%s%w%o%r%l%d%"
But I'm not sure how that would go performance wise and if this is the best solution for it.
Is adding % a good solution?
Any other tips on how to make a good working query?
Progress:
After a bit of testing I found that adding lots of wildcards (%) is not a good idea. You will get returned unexpected results from the database, simply because you just added a lot of ways things could match.
Using the slug method seems to be the only option.
If i get your question well, you are creating a way of searching through those informations. And if that is the case then try
$query = addslashes($query);
SELECT name
FROM giveaway
WHERE gamename LIKE '%$query%'
Now if you want to enlarge your search and search for every single word that looks like the words in your string, then you can explode the text and search for each word by doing
<?php
$query = addslashes($query);
//We explode the query into a table
$tableau=explode(' ',$query);
$compter_tableau=count($tableau);
//We prepare the query
$req_search = "SELECT name FROM giveaway WHERE ";
//we add the percentage sign and the combine each query
for ($i = 0; $i < $compter_tableau; $i++)
{
$notremotchercher=$tableau["$i"];
if($i==$compter_tableau) { $liaison="AND"; } else { $liaison=""; }
if($i!=0) { $debutliaison="AND"; } else { $debutliaison=""; }
$req_search .= "$debutliaison gamename LIKE '%$notremotchercher%' $liaison ";
}
//Now you lauch your query here
$selection=mysqli_query($link, "$req_search") or die(mysqli_error($link));
?>
By so doing you would have added the % to every word in your query which will give you more result that you can choose from.

Codeigniter return result and row

In the Model class I use return $query->row(); to return single rows and return $query->result(); when returning multiple rows.
On a single page I have to return single rows and multiple rows from 2 separate tables.
Table users contains general information like the user name, full name, and email address.
Table user_links contains links submitted by the respective user and has multiple rows for each user.
My query
$this->db->select('*');
$this->db->from('users');
$this->db->join('user_links', "user_links.user_id = users.user_id");
$this->db->where('users.user_id', $user_id);
$this->db->where('user_links.user_id', $user_id);
$query = $this->db->get();
return $query->row();
In my controller I load the query in my view by
$data['row'] = $this->User_model->user_read($user_id);,
$user_id being the 3rd URL segment containing the unique user id.
Finally, in my view I retrieve rows by echo $row->first_name;
This works for single rows but how can I create a foreach loop for user links? The goal is to avoid loops for single rows and use them just for retrieving multiple rows.
This is psuedo code but you can probobly do something like this
$this->db->select('*');
$this->db->from('users');
$this->db->join('user_links', "user_links.user_id = users.user_id");
$this->db->where('users.user_id', $user_id);
$this->db->where('user_links.user_id', $user_id);
$query = $this->db->get();
if ($query->num_rows() == 1)
{
return $query->row();
}
elseif ($query->num_rows() > 1)
{
return $query->result_array(); //This returns an array of results which you can whatever you need with it
}
else
{
//Add some logic to handle if there are zero results
}
If I understand your question correctly, you want to get both the user data as well as user_links data with a single query while avoiding iterating through it to get the user's data. While this may be possible using result_array, I would advise against it since you will get 0 results when there are no entries in user_links for that particular user.
My suggestion is that you use two queries, one to get the user from the user table, another to get user's links from user_links table. This will also help you avoid joins.
Hard to tell what you want.
You want a function that checks if you're passing a row() or a result() and treat them accordingly.
In my opinion your code would be easier to read (and maintain) if you just passed everything as a result(). And do check if the set is empty to show a nice message to the user.
Sounds like you're looking for some of the other features already provided by CI's Active Record: http://codeigniter.com/user_guide/database/results.html
For what you are doing it sounds like using the built in function result_array would work. You use it like so:
TAKEN FROM LINK ABOVE
$query = $this->db->query("YOUR QUERY");
foreach ($query->result_array() as $row)
{
echo $row['title'];
echo $row['name'];
echo $row['body'];
}
You can just replace this line:
$this->db->join('user_links', "user_links.user_id = users.user_id");
With this one:
$this->db->join('user_links', "user_links.user_id = users.user_id", 'left outer');
Join in codeigniter uses INNER JOIN by default but in some cases if there is no data in user_links it returns nothing so u can use LEFT JOIN in your frame work CI it used like i mentioned above.

Searching Database PHP/MYSQL Question

Right now I'm just using a simple
WHERE name LIKE '%$ser%'
But I'm running into an issue - say the search is Testing 123 and the "name" is Testing, it's not coming back with any results. Know any way to fix it? Am I doing something wrong?
If you want to search for 'Testing' or '123' use OR:
WHERE (name LIKE '%Testing%' OR name LIKE '%123%')
Note however that this will be very slow as no index can be used and it may return some results you didn't want (like "4123"). Depending on your needs, using a full text search or an external database indexing product like Lucene might be a better option.
That's how LIKE works - it returns rows that completely contain the search string, and, if you use "%" optionally contain something else.
If you want to see if the field is contained in a string, you can do it this way:
SELECT * FROM `Table` WHERE "Testing 123" LIKE CONCAT("%",`name`,"%")
As Scott mentioned, you cannot check to see if the search contains the column value, it works the other way round.
so if $ser = "testing" and table has a row name = testing 123 it will return
For what you're trying to do you'll need to tokenize the search query into terms and perform an OR search with each of them or better still check out mysql full text search for a much better approach
After the variable $ser is replaced, the query is:
WHERE name LIKE '%Testing 123%'
You should build the query separating by words:
WHERE name LIKE '%$word[1]%$word[2]%'
not efficient (as your example) but working as you want:
WHERE name LIKE '%$ser%' OR '$ser' LIKE CONCAT('%', name, '%')
As mentioned by Mark and others, a full text search method may be better if possible.
However, you can split the search string on word boundary and use OR logic—but check for the whole string first, then offer the option to widen the search:
NOTE: Input sanitization and preparation not shown.
1. Query with:
$sql_where = "WHERE name LIKE '%$ser%'";
2. If zero results are returned, ask user if they would like to query each word individually.
3. If user requests an 'each word' search, query with:
$sql_where = get_sql_where($ser);
(Working) Example Code Below:
$ser = 'Testing 123';
$msg = '';
function get_sql_where($ser){
global $msg;
$sql_where = '';
$sql_where_or = '';
$ser = preg_replace("/[[:blank:]]+/"," ", trim($ser)); //replace consecutive spaces with single space
$search_words = explode(" ", $ser);
if($search_words[0] == ''){
$msg = 'Search quested was blank.';
}else{
$msg = 'Search results for any of the following words:' . implode(', ', $search_words);
$sql_where = "WHERE name LIKE '%$ser%'";
foreach($search_words as $word){
$sql_where_or .= " OR name LIKE '%$word%'";
}
}
return $sql_where . $sql_where_or;
}
$sql_where = get_sql_where($ser);
//Run query using $sql_where string

Categories