How to generate seo friendly url's with php? - php

I want to make http://mysite.com/id255/ to http://mysite.com/gora-beach-inn/.
My php looks like:
$result = mysql_query("
SELECT id, header
FROM Article
");
while($data = mysql_fetch_assoc($result)){
mysql_query("
UPDATE Article
SET seo = '".MakeSeo($data['header'])."'
WHERE datum = '".$data['datum']."'
");
}
//Convert: "åäö" to "aao", "space" to "-", "!?" to "nothing", and all to lower case.
function MakeSeo($string)
{
???
}
Please help me with the MakeSoe function.
I use moderewrite, so I just need help to generate the url, so I can save them in my database.

To just answer your requirement ..
here you go ..
function makeSeo($text, $limit=75)
{
// replace non letter or digits by -
$text = preg_replace('~[^\\pL\d]+~u', '-', $text);
// trim
$text = trim($text, '-');
// lowercase
$text = strtolower($text);
// remove unwanted characters
$text = preg_replace('~[^-\w]+~', '', $text);
if(strlen($text) > 70) {
$text = substr($text, 0, 70);
}
if (empty($text))
{
//return 'n-a';
return time();
}
return $text;
}
You can add more filters to clean the url and may be you add some more stuff to get that url a unique.
Note: I am not saying that adding url to the database is the best way. You could achieve the same sort of functionality using other techniques, for example, mod_rewrite.

You would need to use mod_rewrite to achieve this, otherwise the other approach is the 'internal' method done by php, where you would do something similar to:
http://mydomain.com/index.php/category/dogs
the above is just a GET post, and index handles the content loading via includes / mysql etc;

Non regular expression and more flexible solution can be done via 2 arrays. Define all charcters in from and to arrays. Omitted characters will be than replaced by -
This is example of javascript function
function ToSeoFriendly(title) {
title = title.toLowerCase();
var generated = "";
var from = "ãàáäâẽèéëêìíïîõòóöôùúüûñçýčšžřľňäôabcdefghijklmnopqrstuvwxyz1234567890";
var to = "aaaaaeeeeeiiiiooooouuuuncycszrlnaoabcdefghijklmnopqrstuvwxyz1234567890-";
for (var i=0;i<title.length;i++){
generated += to.substr(from.indexOf(title.substr(i,1)),1);
}
return generated;
}

Related

PHP match and replace whole word

Hi I am replacing certain names with different value . Here is values I am replacing "#size-name" and "#size" .But the problem is my code replacing only size first and note name for example
#size = "replaceword"
#size-name = "replaceword2"
But its replacing
#size ="replaceword"
#size-name = "replaceword2-name"
How can I replace whole word not part of it here is my code
$tempOutQuery = preg_replace("/(\b($key)\b)/i" , $value , $tempOutQuery);
$tempOutQuery= str_replace("#".$key ,$value ,$tempOutQuery);
both codes are not working
My Full Code
$val= "Hi I want #size dress which is #size-name";
$tempOutQuery = preg_replace("/(\b(size)\b)/i" ,"replaceword", $tempOutQuery);
$tempOutQuery = preg_replace("/(\b(size-name)\b)/i" ,"replaceword2", $tempOutQuery);
If you could make replace without using regulat expressions, then I would suggest using standart str_replace() with arrays:
$val= "Hi i want #size dress which is #size-name";
$search = array('size-name', 'size');
$replace = array('replaceword2', 'replaceword');
$result = str_replace($search, $replace, $val);
The order of search and replace Strings is important!
You should take care that you replace long search-strings first, and the short strings later.
Here's another option for you, using preg_replace_callback. It's actually very similar to Gennadiy's method. The only real difference is that it's using the preg aspect of PHP (and it's a lot more work). But it's another way to skin the proverbial cat.
<?php
// SET OUR DEFAULT STRING
$string = 'Hi I want #size suit which is #size-name';
// LOOK FOR EITHER size-name OR size AND IF YOU FIND IT ...
// RUN THE FUNCTION 'replace_sizes'
$string = preg_replace_callback('~#(size-name|size)~', 'replace_sizes', $string);
// PRINT OUT OUR MODIFIED STRING
print $string;
// THIS IS THE FUNCTION THAT WILL BE RUN EVERY TIME A MATCH IS FOUND
// EITHER 'size' OR 'size-name' WILL BE STORED IN $m[1]
function replace_sizes($m) {
// SET UP AN ARRAY THAT HAS OUR POTENTIAL MATCHES AS KEYS
// AND THE TEXT WE WANT TO REPLACE WITH AS THE VALUE
$size_text_array = array('size-name' => 'replaceword2', 'size' => 'replaceword');
// RETURN WHATEVER THE VALUE IS BASED ON THE KEY
return $size_text_array[$m[1]];
}
This will print out:
Hi I want replaceword suit which is replaceword2
Here is a working demo:
http://ideone.com/njNTbB
You can try pre_replace() to replace whole word from an item of an array in PHP a shown below.
<?PHP
function removePrepositions($text){
$propositions=array('/\bfor\b/i','/\band\b/i');
if( count($propositions) > 0 ) {
foreach($propositions as $exceptionPhrase) {
$text = preg_replace($exceptionPhrase, '', trim($text));
}
$retval = trim($text);
}
return $retval;
}
?>
See the entire post here

PHP regex for image name with numbers

I have images with names such as:
img-300x300.jpg
img1-250x270.jpg
These names will be stored in a string variable. My image is in Wordpress so it will be located at e.g.
mywebsite.com/wp-content/uploads/2012/11/img-300x300.jpg
and I need the string to be changed to
mywebsite.com/wp-content/uploads/2012/11/img.jpg
I need a PHP regular expression which would return img.jpg and img1.jpg as the names.
How do I do this?
Thanks
Addition
Sorry guys, I had tried this but it didn't work
$string = 'img-300x300.jpg'
$pattern = '[^0-9\.]-[^0-9\.]';
$replacement = '';
echo preg_replace($pattern, $replacement, $string);
You can do this using PHP native functions itself.
<?php
function genLink($imagelink)
{
$img1 = basename($imagelink);
$img = substr($img1,0,strrpos($img1,'-')).substr($img1,strpos($img1,'.'));
$modifiedlink = substr($imagelink,0,strrpos($imagelink,'/'))."/".$img;
return $modifiedlink;
}
echo genLink('mywebsite.com/wp-content/uploads/2012/11/flower-img-color-300x300.jpg');
OUTPUT :
mywebsite.com/wp-content/uploads/2012/11/flower-img-color.jpg
You can do that as:
(img\d*)-([^.]*)(\..*)
and \1\3 will contain what you want:
Demo: http://regex101.com/r/vU2mD4
Or, replace (img\d*)-([^.]*)(\..*) with \1\3
May be this?
(\w+)-[^.]+?(\.\w+)
The $1$2 will give you what you want.
search : \-[^.]+
replace with : ''
(.[^\-]*)(?:.[^\.]*)\.(.*)
group 1 - name before "-"
group 2 - extension. (everything after ".")
As long as there is only one - and one . then explode() should work great for this:
<?php
// array of image names
$images = array();
$images[] = 'img-300x300.jpg';
$images[] = 'img1-250x270.jpg';
// array to store new image names
$new_names = array();
// loop through images
foreach($images as $v)
{
// explode on dashes
// so we would have something like:
// $explode1[0] = 'img';
// $explode1[1] = '300x300.jpg';
$explode1 = explode('-',$v);
// explode the second piece on the period
// so we have:
// $explode2[0] = '300x300';
// $explode2[1] = 'jpg';
$explode2 = explode('.',$explode1[1]);
// now bring it all together
// this translates to
// img.jpg and img1.jpg
$new_names[] = $explode1[0].'.'.$explode2[1];
}
echo '<pre>'.print_r($new_names, true).'</pre>';
?>
That's an interesting question, and since you are using php, it can be nicely solved with a branch reset (a feature of Perl, PCRE and a few other engines).
Search: img(?|(\d+)-\d{3}x\d{3}|-\d{3}x\d{3})\.jpg
Replace: img\1.jpg
The benefit of this solution, compared with a vague replacement, is that we are sure that we are matching a file whose name matches the format you specified.

Replace text if it matches another piece of text

So I have the following code to remove "page=" from a string. My problem now is that I want to query through "$qs_final" to check if it contains "price_range" and if so replace it with another piece of text. The price range variable is attached to "attr=" so I can't really use a $_GET request as other information is stored within it. The price_range variable also has the layout of "price_range_20".
<?php
$querystring = explode("&",$_SERVER['QUERY_STRING']);
$qs_nos = 0;
$qs_final = "";
while(isset($querystring[$qs_nos])) {
if(!ereg("page=",$querystring[$qs_nos])) {
$qs_final .= $querystring[$qs_nos]."&";
}
$qs_nos++;
}
if (strpos($qs_final,'price_range') !== false) {
print "true";
}
?>
str_replace().
$new_string = str_replace($what_to_replace, $what_to_replace_it_with, $old_string);
EDIT: To replace data, you need preg_replace(). In your case to remove "price_range" and all numbers and underscores directly after it, use this:
$new_string = preg_replace("/price_range[0-9_]+/", "", $old_string);

PHP SEO Functions

I am having a problem trying to understand functions with variables. Here is my code. I am trying to create friendly urls for a site that reports scams. I created a DB full of bad words to remove from the url if it is preset. If the name in the url contains a link I would like it to look like this: example.com-scam.php or html (whichever is better). However, right now it strips the (.) and it looks like this examplecom. How can I fix this to leave the (.) and add a -scam.php or -scam.html to the end?
functions/seourls.php
/* takes the input, scrubs bad characters */
function generate_seo_link($link, $replace = '-', $remove_words = true, $words_array = array()) {
//make it lowercase, remove punctuation, remove multiple/leading/ending spaces
$return = trim(ereg_replace(' +', ' ', preg_replace('/[^a-zA-Z0-9\s]/', '', strtolower($link))));
//remove words, if not helpful to seo
//i like my defaults list in remove_words(), so I wont pass that array
if($remove_words) { $return = remove_words($return, $replace, $words_array); }
//convert the spaces to whatever the user wants
//usually a dash or underscore..
//...then return the value.
return str_replace(' ', $replace, $return);
}
/* takes an input, scrubs unnecessary words */
function remove_words($link,$replace,$words_array = array(),$unique_words = true)
{
//separate all words based on spaces
$input_array = explode(' ',$link);
//create the return array
$return = array();
//loops through words, remove bad words, keep good ones
foreach($input_array as $word)
{
//if it's a word we should add...
if(!in_array($word,$words_array) && ($unique_words ? !in_array($word,$return) : true))
{
$return[] = $word;
}
}
//return good words separated by dashes
return implode($replace,$return);
}
This is my test.php file:
require_once "dbConnection.php";
$query = "select * from bad_words";
$result = mysql_query($query);
while ($record = mysql_fetch_assoc($result))
{
$words_array[] = $record['word'];
}
$sql = "SELECT * FROM reported_scams WHERE id=".$_GET['id'];
$rs_result = mysql_query($sql);
while ($row = mysql_fetch_array($rs_result)) {
$link = $row['business'];
}
require_once "functions/seourls.php";
echo generate_seo_link($link, '-', true, $words_array);
Any help understanding this would be greatly appreciated :) Also, why am I having to echo the function?
Your first real line of code has the comment:
//make it lowercase, remove punctuation, remove multiple/leading/ending spaces
Periods are punctuation, so they're being removed. Add . to the accepted character set if you want to make an exception.
Alter your regular expression (second line) to allow full stops:
$return = trim(ereg_replace(' +', ' ', preg_replace('/[^a-zA-Z0-9\.\s]/', '', strtolower($link))));
The reason your code needs to be echoed is because you are returning a variable in the function. You can change return in the function to echo/print if you want to print it out as soon as you call the function.

Can I use regex for this?

Is this possible with regex?
I have a file, and if a '#' is found in the file, the text after the '#' with the '#' is to be replaced with the file with the same name as after the '#'.
File1: "this text is found in file1"
File2: "this file will contain text from file1: #file1".
File2 after regex: "this file will contain text from file1: this text is found in file1".
I wish to do this with php and I've heard that the preg function is better than the ereg, but whatever works is fine with me =)
Thanks a lot!
EDIT:
It has to be programmed, so that it looks through file2 without knowing which files to concatenate before it has gone through all occurrences of a # :)
PHP's native functions str_pos and str_replace are better to use when you're searching through larger files or strings. ;)
First of all the grammar of your templating is not a very good one becuase the parser may not exactly sure when will the file name ends.
My suggestion would be that you change to the one that can better detect the boundry like {#:filename}.
Anyhow, the code I give below follows your question.
<?php
// RegEx Utility functions -------------------------------------------------------------------------
function ReplaceAll($RegEx, $Processor, $Text) {
// Make sure the processor can be called
if(!is_callable($Processor))
throw new Exception("\"$Processor\" is not a callable.");
// Do the Match
preg_match_all($RegEx, $Text, $Matches, PREG_OFFSET_CAPTURE + PREG_SET_ORDER);
// Do the replacment
$NewText = "";
$MatchCount = count($Matches);
$PrevOffset = 0;
for($i = 0; $i < $MatchCount; $i++) {
// Get each match and the full match information
$EachMatch = $Matches[$i];
$FullMatch = is_array($EachMatch) ? $EachMatch[0] : $EachMatch;
// Full match is each match if no grouping is used in the regex
// Full match is the first element of each match if grouping is used in the regex.
$MatchOffset = $FullMatch[1];
$MatchText = $FullMatch[0];
$MatchTextLength = strlen($MatchText);
$NextOffset = $MatchOffset + $MatchTextLength;
// Append the non-match and the replace of the match
$NewText .= substr($Text, $PrevOffset, $MatchOffset - $PrevOffset);
$NewText .= $Processor($EachMatch);
// The next prev-offset
$PrevOffset = $NextOffset;
}
// Append the rest of the text
$NewText .= substr($Text, $PrevOffset);
return $NewText;
}
function GetGroupMatchText($Match, $Index) {
if(!is_array($Match))
return $Match[0];
$Match = $Match[$Index];
return $Match[0];
}
// Replacing by file content -----------------------------------------------------------------------
$RegEx_FileNameInText = "/#([a-zA-Z0-9]+)/"; // Group #1 is the file name
$ReplaceFunction_ByFileName = "ReplaceByFileContent";
function ReplaceByFileContent($Match) {
$FileName = GetGroupMatchText($Match, 1); // Group # is the gile name
// $FileContent = get_file_content($FileName); // Get the content of the file
$FileContent = "{# content of: $FileName}"; // Dummy content for testing
return $FileContent; // Returns the replacement
}
// Main --------------------------------------------------------------------------------------------
$Text = " === #file1 ~ #file2 === ";
echo ReplaceAll($RegEx_FileNameInText, $ReplaceFunction_ByFileName, $Text);
This will returns === {# content of: file1} ~ {# content of: file2} ===.
The program will replace all the regex match with the replacement returned from the result of the given function name.
In this case, the callback function is ReplaceByFileContent in which the file name is extract from the group #1 in the regex.
I believe my code is self documented but if you have any question, you can ask me.
Hope I helps.
Much cleaner:
<?php
$content = file_get_content('content.txt');
$m = array();
preg_match_all('`#([^\s]*)(\s|\Z)`ism', $content, $m, PREG_SET_ORDER);
foreach($m as $match){
$innerContent = file_get_contents($match[1]);
$content = str_replace('#'.$match[1], $innerContent, $content);
}
// done!
?>
regex tested with: http://www.spaweditor.com/scripts/regex/index.php

Categories