php, how to get the keywords out of an url? - php

the question might be a bit confusing, so here is what i have:
i insert in the database the previous link where a person came from like tihs:
$came_from = $_SERVER['HTTP_REFERER']; // get previous link
if the link is from google.com it will come like this:
http://www.google.com/#sclient=psy&hl=en&source=hp&q=this+is+a+test&pbx=1&oq=this+is+a+teat&aq=f&aqi=g-s1g-v1&aql=1&gs_sm=s&gs_upl=887l82702l3.10.3.1l17l0&bav=on.2,or.r_gc.r_pw.r_cp.&fp=c3d3303&biw=1920&bih=995
if we look inside we can find q=this+is+a+testas beeing the keywords that i search for.
my question is how can i create a query to return http://www.google.com/ | this+is+a+test ?
i know that the keywords have the + sign in between them.
so far i came up with this, but not exactly what i wanted:
SELECT SUBSTRING_INDEX (table, '+', 1), table FROM table.table WHERE table LIKE '%+%' LIMIT 20
any ideas?
thanks
edit: what happend is that sometimes i get some other url's that don't have q= but maybe seearch=, so i want to keep track of the + sign

As it's been pointed out, you can't reliably get the keywords without supplying the parameters to look for. Here's what I would do:
$url = 'http://www.google.com/#sclient=psy&hl=en&source=hp&q=this+is+a+test&pbx=1&oq=this+is+a+teat&aq=f&aqi=g-s1g-v1&aql=1&gs_sm=s&gs_upl=887l82702l3.10.3.1l17l0&bav=on.2,or.r_gc.r_pw.r_cp.&fp=c3d3303&biw=1920&bih=995';
$possible = array('q', 'ssearch', 'oq');
$query_str = NULL;
foreach ($possible as $search) {
if (isset($arr[$search])) {
$query_str = $arr[$search];
break;
}
}
Basically all this does is parse the url using PHP's parse_str() and look for the parameter q. If it's not there, it uses ssearch, and then oq. You can add more of them if you need to. If by the end of it it's not found, $query_str will be NULL.
Unless you have a very compelling reason to do it with MySQL only, just process everything on the PHP side. Databases are made to store data, not process it. What I would do is have PHP figure out the search engine and the keywords used and insert those into the DB, as separate fields. ie, have a table like so:
search_engine | query_str
------------- | -----------
google | test
yahoo | something
...

If you know that you need q=... then you can use regexp. I will update post if that's what you need.

As everyone is saying, you need to use the key value (in your example, q). In MySQL, you can do something like this:
SELECT SUBSTRING_INDEX(table, '?q=', -1), table FROM table.table WHERE table LIKE '?' LIMIT 20
I'd also suggest you rename your table column to something other than 'table'.

Related

having trouble search through mysql database

I have two questions regarding my script and searching. I have this script:
$searchTerms = explode(' ', $varSearch);
$searchTermBits = array();
foreach($searchTerms as $term){
$term = trim($term);
if(!empty($term)){
$searchTermBits[] = "column1 LIKE '%".$term."%'";
}
}
$sql = mysql_query("SELECT * FROM table WHERE ".implode(' OR ', $searchTermBits)."");
I have a column1 with a data name "rock cheer climbing here"
If I type in "rock climb" this data shows. Thats perfect, but if I just type "Rocks", it doesn't show. Why is that?
Also, How would I add another "column2" for the keyword to search into?
Thank you!
Searching that string for "rocks" doesn't work, because the string "rocks" doesn't exist in the data. Looking at it, it makes sense to you, because you know that the plural of "rock" is "rocks", but the database doesn't know that.
One option you could try is removing the S from search terms, but you run into other issues with that - for example, the plural of "berry" is "berries", and if you remove the S, you'll be searching for "berrie" which doesn't get you any further.
You can add more search terms by adding more lines like
$searchTermBits[] = "column1 LIKE '%".$term."%'";
and replacing ".$term." with what you want to search for. For example,
$searchTermBits[] = "column1 LIKE '%climb%'";
One other thing to note... as written, your code is susceptible to SQL injection. Take this for example... What if the site visitor types in the search term '; DROP TABLE tablename; You've just had your data wiped out.
What you should do is modify your searchTermBits[] line to look like:
$searchTermBits[] = "column1 LIKE '%" . mysql_real_escape_string($term) . "%'";
That will prevent any nastiness from harming your data.
Assuming the data you gave is accurate, it shouldn't match because you're using "Rocks" and the word in the string is "rock". By default mysql doesn't do case sensitive matching, so it's probably not the case.
Also, to avoid sql injection, you absolutely should be using mysql_real_escape_string to escape your content.
Adding a second column would be pretty easy as well. Just add two entries to your array for every search term, one for column1 and one for column2.
Your column1 data rock cheer climbing here your search criteria %Rocks% it doesn't fit at all as rocks is not in your column1 data
you can add column2 as you do for column1 then put it all together by using an AND operator (column1 LIKE "%rock%" OR column1 LIKE "%climb%") AND (column2 LIKE "%rope%" OR column2 LIKE "%powder%")
TIPS:
If your table/schema are using xx_xx_ci collation (then this is mean case insensitive,mysql doesn't care case sensitive) but if other then you need to make sure that the search term must be case sensitive(mysql do case sensitive).

create mention like twitter or convore with php

hello im just curious. about how they do stuff. what i assume they do something like this
#someone1 im stacking on stackoverflow RT #someone2 : hello guys what are you doing?
before i do it in my way i want to tell you about my database scheme
// CID = COMMENT ID, BID = BLOG ID, UID = USER ID
CID BID UID COMMENT
1 1 1 #someone1 im stacking on stackoverflow RT #someone2 : ....
2 1 4 #someone1 im stacking on stackoverflow RT #someone2 : ....
3 1 12 #someone1 im stacking on stackoverflow RT #someone2 : ....
they use regex to do like this to take the #someones name
preg_match_all("/#[a-zA-Z0-9_]+/", $text, $matches);
then they get the # off each name
foreach ($matches as $value) {
foreach ($value as $value) {
$usernames[] = substr($value, 1);
}
}
then they get the UID from the database from doing something like this
foreach ($username as $value) {
# insert database one by one ? so it will be like the example above
}
then we can just output the comment buy geting the UID.
then somhow we can get all the comments in the blog. ( without a same comment ) where blog buid = 1 and give them an notification on every user by where uid = :uid.
is there any better way doing this ? something like twitter or convore ?
Thanks for looking in
Adam Ramadhan
I have done something similar to this with an in-house application that we use for communication.
Basically, you are going to have two tables: status_updates and mentions. Each status update has many mentions. Whenever someone creates a status update, you save it to the status_updates table. During this process, you can also use Regex to detect any #username "mentions". When you find a mention, you add it to your mentions table. For example, your mentions table might look something like this:
mention_id (Auto-incrementing key) | status_message_id | username_id
That way if you want to see if someone is mentioned in a status message you can do a quick lookup in the status_messages table, as opposed to loading up the status message and running the Regex each time. The other nice thing about this approach is that it allows you to have multiple mentions in each status message. Just create a record in mentions for each.
That's the basic way that we have set it up.
EDIT: If you wanted to pull an "activity feed" for a given user, showing only the status updates in which they have been mentioned, it would be as simple as:
SELECT * FROM mentions m LEFT JOIN status_messages s ON m.status_message_id = s.id WHERE m.username_id = $username_id
I should note that this is not how they do it at Twitter, because they are dealing with issues of scale that would make this simple way of doing things impossible. However, I think this is the simplest solution that works well if you aren't worried about scaling to hundreds of thousands of users. If you are, then you probably have more issues on your hands than this.
You can use it like bb codes but instead of taken it like [foo] [/foo] you take the # and end it at the space ... before it's insert into your database you take another script and break the # after the space. and put the mention into a separate column then use bbcodes to make the mention on the fly
Example..
if ( strstr("$status", "#") ) {
$explodeat = explode("#", $status);
$explodeat1 = explode(" ", $explodeat[1]);
$status=$explodeat1[0];
}
and insert $status into your mentions column in your database... The BB code for it after that won't be so hard
I think in MySQL, you can use DISTINCT to avoid duplicates rows:
Something link this:
SELECT `CID`, `BID`, DISTINCT `COMMENT`
FROM comments
WHERE UID = :uid
AND ##Others clauses for bloc here##

how to updated the keywords from database

hi i have stored 1000 keywords in my database . if i search any keyword(with in my database) my site title must come Like a AIRPORT NETWORKS this title i want . this is for search engine box. how can i do with sql queries i used that below query for displayed my site title.
$ConvertedResultArray = explode('<div id="resultsDiv">', $ConvertedResult);
$V1 = $ConvertedResultArray[0];
$V2 = $ConvertedResultArray[1];
$SponsoredContent = '';
if(strtolower($SearchQuery) == 'taxi')
{
$SponsoredContent = '<br />AIRPORTS<br />NETWORKS';
}
$ConvertedResult = "$V1$SponsoredContent$V2";
i have a only one table named keywords
if i entered that key "taxi" in search box That title comes infront of the page AIRPORTNETWORKS as like that if i entered in the whole 1000 words which it is stored in database it must be come .
how can i do that what sql query i have to use.is it possible. please help me if any one have an idea thanks in advance
I realise this not the answer, but here is something to get you started
SELECT *
FROM Keywords
WHERE Name LIKE "%AIRPORT%"
You need to use AJAX for that. I guess you are speaking about auto complete. if is tat you are talking about do the following steps.
1. use the query given by PerformanceDBA
2. update the textbox value with the first row of query result by triggering textbox onkeyup() event.
If this is not what you want please rephrase your question so tat others can understand..

MySQL: How to search for spelling variants? ("murrays", "murray's" etc)

I want to search like this: the user inputs e.g. "murrays", and the search result will show both records containing "murrays" and records containing "murray's". What should I do in my query.pl?
What do you think about using the SOUNDEX function and the SOUNDS LIKE operator ?
That way, you can simply do:
SELECT * from USERS WHERE name SOUNDS LIKE 'murrays'
I'm pretty sure it doesn't work for every case, and perhaps it is not the most efficient way to solve the problem, but it could fit your needs.
This won't help if you absolutely need to do these queries in SQL, but if you can set up a Lucene search index for it, you gain a lot of this kind of "fuzzy search" functionality. Note though that Lucene is quite a complex topic by itself.
What you could do is create an extra field in the database, which contains the data with all special characters stripped from it, and search there. A bit lame, I know. Looking forward to see smarter answers ;)
Quick and dirty:
SELECT * FROM myTable WHERE REPLACE(name, '\'', '') = 'murrays'
I would first build a search column which has the text without punctuation and then search on that. Otherwise you'll have have to have a series of regular expressions to search against or check individual records in PHP for matching: both of which are computational intensive operations.
Maybe something like this: (untested!)
SELECT * FROM users WHERE REPLACE(user_name, '\'', '') = "murrays"
If this is for single word searching, you could try using Soundex or Metaphone functions? These would handle sounds-like as well as spelling
Not sure if MySQL has these, but PHP does (which would require separate columns to hold these values).
Otherwise, Richy's no-punctuation extra column seems best.
You could try adding a replace to your query like this
replace(name, '''','')
to temporarily get rid of the apostrophes for the match.
select name from nametable where name = replace(name,'''','');
This query should be able to pick up "murrays" or "murray's".
var inputStr = "murrays";
inputStr = String.Replace("'", "\'", inputStr);
SELECT * FROM ATable WHERE Replace(AField, '\'', '') = inputStr OR AField = inputStr
strip user input and names in database from all non-letter characters.
Use levenstein distance or soundex to find murrays with murray or marrays. This is optional but your users would love that.

Why is my MySQL INSERT query inserting 3 identical rows?

I am trying to track what users are searching for on my site (from a simple search form on the front page) with PHP and MySQL.
At the end of all my queries I am using this query:
INSERT INTO `DiggerActivity_Searches` (
`SearchTerms`,
`SearchType`,
`NumResults`,
`Location`,
`Date`,
`Time`
) VALUES (
'SearchKeywords',
'SearchTypes',
'NumberOfResults',
'User'sLocation',
'CurDate',
'CurTime'
)
Now, whenever there is a new search keyword, it inserts 3 identical rows. However, if I refresh the page it only inserts 1 row, as it should.
The values are passed as a GET like this (I have mod rewritten the URL stuff):
http://www.mysite.com/Search-Category-Search_these_words
You might want to check first whether your script executes the query three times or the script is invoked three times (e.g. by some browser addons).
If you do not have a debugger installed you can use something like
function trace_log() {
static $magic = null;
if (is_null($magic)) {
$magic = uniqid();
}
$s = $magic . ' '. microtime(true) . ":\r\n";
foreach( debug_backtrace() as $d) {
$s .= ' '. $d['file'].'#'.$d['line']."\r\n";
}
file_put_contents('trace_log.txt', $s, FILE_APPEND);
}
...
trace_log();
mysql_query(....) // or stmt->execute() or whatever you use to execute the query.
If the first value of each log entry (the "magic" id) in trace_log.txt changes, your script is invoked multiple times. If it's the same for all three calls to trace_log(), your script executes the query three times.
Your table is missing a primary key. Id suggest a PK like search ID or something similar
Read more about this at Unique key - Wikipedia
Just know you are not alone in dealing with this strange bug.
This same problem showed up on my website in the past few days as well. The only thing I recently added was a third party banner ad.
SOLUTION: I commented out the banner ad script (Hint: from search engine that starts with a G) and everything was good again.
I was just going to make a comment put need more reputation to so...
Anyway, similar happened to me. Turns out I was echoing out debug information above the header causing the browser to reload automatically. Easiest way to check is just use
<script type="text/javascript">alert("loading");</alert>
in the header and see how many times you see it.

Categories