ساخت کوتاه کننده لینک با PHP به صورت Ajax

دی ۱۵, ۱۳۹۱ توسط : سعید

سلام

به احتمال زیاد تا به حال به سایتهایی برخوردید که یک لینک بزرگ میگیرن و به یک لینک کوچیک تبدیلش میکنن.سایتهایی مثل tinyurl.com , bit.ly و … . در این پست میخوام آموزش ساخت کوتاه کننده لینک به وسیله PHP به صورت ای جکس رو آموزش بدم.امیدوارم به دردتون بخوره.

سورس رو از اینجا دانلود کنید

دمو رو اینجا ببینید

دیتابیس این پروژه رو میسازیم :

CREATE TABLE IF NOT EXISTS `urls` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `url` varchar(500) NOT NULL,
  `short_code` varchar(15) NOT NULL,
  `create_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `visits` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;

بعد از ساخت دیتابیس بالا در فایل  config.php کدهای زیر رو بنویسید و مقدار دهی کنید :

<?php

define('DB_HOST','localhost');
define('DB_NAME','database_name');
define('DB_USERNAME','database_username');
define('DB_PASSWORD','database_password');
define('SITEURL','http://url.phpro.ir/');

date_default_timezone_set('Asia/Tehran');

حب برای ساخت لینکهای کوتاه و ذخیره در دیتابیس کلاسی مینوسیم به نام UrlShortener که در زیر به توضیح کلاس میپردازیم :

این کلاس ۶ متد داره و از کتابخانه PDO برای اتصال با Mysql استفاده میکنه :

<?php
/**
* UrlShortener Class
* 
* @author Saeed Moghadam Zade
* @author URL : http://phpro.ir
* 
* 
* Database Create :
* CREATE TABLE `url_shortener`.`urls` (
* `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
* `url` VARCHAR( 500 ) NOT NULL ,
* `short_code` VARCHAR( 15 ) NOT NULL ,
* `visits` int NOT NULL ,
* `create_time` TIMESTAMP NOT NULL
* ) ENGINE = MYISAM ;
*/
class UrlShortener
{

	private $pdo;

	function __construct()
	{
		$this->pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME,DB_USERNAME,DB_PASSWORD);

	}

	/**
	* Create short code
	* 
	*/
	function createShortCode($url = '')
	{
		$chars = "123456789bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ";
		$short_code = '';
		while(strlen($short_code) < 7)
		{
			$short_code .= $chars[rand(0,strlen($chars))];
		}
		// check in db
		$stm = $this->pdo->prepare('select * from urls where short_code = :short');
		$stm->execute(array('short'=>$short_code));
		$res = $stm->fetch();
		print_r($res);

		return $short_code;
	}

	/**
	* return true if url format valid
	* 
	*/
	function validUrl($url)
	{
		return filter_var($url , FILTER_VALIDATE_URL , FILTER_FLAG_HOST_REQUIRED);
	}

	/**
	* Check url exist in db
	* @param $url String
	*/
	function existInDb($url)
	{
		$stm = $this->pdo->prepare('select * from urls where url = \''.$url.'\'');
		$stm->execute();
		$res = $stm->fetch();

		return ( empty($res['short_code']) ? false : $res['short_code']);
	}

	function insertInDb($url)
	{
		// if url exist in db return short code
		if(($short_code = $this->existInDb($url)) !== false)
		{
			return $short_code;
		}
		// insert in db and return short code
		if($this->validUrl($url))
		{
			$short_code = $this->createShortCode($url);
			$stm = $this->pdo->prepare('insert into urls (url , short_code,create_time)values(:url,:short_code,:time)');
			$param = array('url'=>$url,'short_code'=>$short_code,'time'=>date('Y-j-m'));
			$stm->execute($param);
			return $short_code;
		}else
		{
			return 'invalid';
		}

		return false;
	}

	/**
	* return url
	*/
	function getUrl($short_code)
	{
		$stm = $this->pdo->prepare('select * from urls where short_code = :short');
		$stm->execute(array('short'=>$short_code));
		$result = $stm->fetch();

		return $result['url'];
	}

	function addCount($url)
	{
		$stm = $this->pdo->prepare('update urls set visits = visits +1 where url = :url');
		$stm->execute(array('url'=>$url));
	}

}

در متد سازنده یک شیء از کلاس pdo ساختیم و رشته اتصال به دیتابیس رو بهش پاس دادیم.
متد createShortCode : این متد یک رشته به صورت تصادفی ایجاد میکنه اگر رشته در دیتابیس بود یکی دیگه میسازه و برمیگردونه.
متد validUrl : یک url میگیره و فرمت url رو چک میکنه در صورت صحیح بودن true بر میگردونه.
متد existInDb : این متد یک url میگیره و چک میکنه که آیا در دیتابیس ذخیره شده یا خیر
متد insertInDb : این متد هم url مورد نظر رو میگیره . ابتدا چک میکنه اگر در دیتابیس وجود داشت لینک کوتاهش رو برمیگردونه اگر نبود لینک رو به دیتابیس اضاضه میکنه و لینک کوتاه رو برمیگردونه.
متد getUrl : این متد کد کوتاه شده رو میگیره و آدرس مربوط رو برمیگردونه
متد addCount : این هم به اضای هر بازدید از آدرس ها یکی به تعداد فیلد visits اضافه میکنه.

در فایل index.php فقط قسمت کدهای jquery رو توضیح میدم.

<script src="js/jquery.min.js"></script>
		<script>
			$(document).ready(function(){
				$('.btn').live('click',function(e){
				    e.preventDefault();
					var url = $('#url').val();
					$('.result').html('<img src="images/loading.gif" />');
					$.post('shortener.php',{url: url},function(data){
						if(data.short != 'invalid')
							$('.result').html('<a href="'+data.short+'" target="_blank" >'+data.short+'</a>');
						else
							$('.result').html('<div class="error">لینک را درست وارد کنید</div>');
					},'json');
				});
			});
		</script>

در این قسمت هنگامی که کلید ارسال فرم کلیک میشه یک درخواست به صورت post به صفحه shortener.php ارسال میشه و جواب این درخواست با فرمت json  دریافت میشه.

دستور e.preventDefault برای جلوگیری از ارسال فرم هنگام کلیک روی دکمه submit فرم میباشد.

فایل shortebner.php

<?php

include 'includes/config.php';

if(isset($_POST['url']))
{
	$url = $_POST['url'];
	include 'includes/UrlShortener.php';
	$short = new UrlShortener();
	$short_code = $short->insertInDb($url) ; 
	//echo '$short_code';
	$msg['short'] = ($short_code == 'invalid') ? 'invalid' : SITEURL.$short_code;
	echo json_encode($msg);	
}

در این فایل هم روال کار بسیار ساده است.ابتدا فایل مربوط به تنظیمات رو include کردیم.سپس یک شیء از کلاس UrlShortener ایجاد کردیم . سپس آدرس URL رو در دیتابیس ذخیره میکنیم و نتیجه رو با فرمت json نمایش میدیم.

تا اینجا یک لینک از کاربر گرفتیم . برای این لینک یک کد کوتاه ساختیم و در دیتابیس ذخیره کردیم.حالا برای اینکه کاربر بتونه با کلیک رو لینک به url اصلی بره یک فایل با نام goto.php میسازیم و کدهای زیر رو داخلش مینویسیم :

<?php

include 'includes/config.php';
include 'includes/UrlShortener.php';

$short = new UrlShortener();

$url = $short->getUrl($_GET['url']);
if(empty($url))
{
	echo '<h1>404 Not Found</h1><br><a href="'.SITEURL.'">Back To Main Page</a>';
}else
{
	$short->addCount($url);
	header('Location:'.$url);
}

در این فایل کد کوتاهی که در متغیر $_GET[‘url’] قرار گرفته رو در دیتابیس پیدا میکنیم و URL مربوط به این کد رو از دیتابیس میخونیم.در نهایت با دستور header صفحه رو به url مورد نظر انتقال میدیم .در صورتی که کد کوتاه در دیتابیس وجود نداشته باشه صفحه ۴۰۴ به کاربر نمایش داده میشه.

بعد از ایجاد فایل goto.php که در مرحله قبل انجام شد یک فایل .htaccess میسازیم تا به جای آدرس :

http://domain.com/goto.php?url=D3dff34

آدرسهایی با فرمت زیر داشته باشیم :

http://domain.com/D3dff34

پس از ساخت فایل htaccess کدهای زیر رو داخلش بنویسید :

RewriteEngine on

RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f

RewriteRule ^(.*)$ goto.php?url=$1

خب پروژه ما آماده است.

در این آموزش سعی کردم مطالب رو به سرعت بگم چون تقریبا تمام مباحثی که توی این آموزش بود رو قبلا در موردش حرف زدیم و یادگرفتیم.فقط جاهایی که نیاز به توضیح داشت رو توضیح دادم اگر جایی رو متوجه نشدید یکی دوبار کدهارو بالا و پایین کنید دستتون میاد چیکار کردیم.اگر هم سوال داشتید که توی کامنتها بپرسید.

موفق باشید

بازدید : ۱۲۵۶۱

دی ۱۶, ۱۳۹۱ @ ۱:۴۸ ق.ظ

خیلی هم عالی 🙂

پاسخ دادن
دی ۱۶, ۱۳۹۱ @ ۴:۳۲ ب.ظ

خیلی خوب بود. متشکر استاد سعید….

پاسخ دادن
اسفند ۱۰, ۱۳۹۱ @ ۹:۳۰ ب.ظ

عالی بود

پاسخ دادن
Ali Yaghobi
اسفند ۲۳, ۱۳۹۱ @ ۵:۵۷ ب.ظ

خیلی خوب بود.

پاسخ دادن
Ali Yaghobi
اسفند ۲۴, ۱۳۹۱ @ ۱۱:۱۴ ق.ظ

میشه درباره کدهای فایل htaccess توضیح بدین
با سپاس

پاسخ دادن
    سعید
    اسفند ۲۴, ۱۳۹۱ @ ۳:۰۹ ب.ظ

    سلام
    ابتدا خط ۳ و ۴ چک میکنه که آیا آدرس به فایلی اشاره میکنه یا خیر.اگر به فایلی اشاره نمیکنه تمام درخواستها در متغیر url در متد get قرار میگیره و به فایل goto.php ارسال میشه.

    موفق باشید

    پاسخ دادن
علی
اسفند ۲۴, ۱۳۹۱ @ ۳:۱۷ ب.ظ

چه جوری میشه به اسکریپت قسمتی اضافه کرد که کاربر بتونه خودش نام لینک رو انتخاب کنه؟!
با سپاس

پاسخ دادن
اسفند ۲۴, ۱۳۹۱ @ ۱۱:۲۷ ب.ظ

اسکریپت لینک ها رو کوتاه میکنه ولی وقتی روش کلیک میکنی به صفحه ارور ۴۰۴ میره
مشکل از کجاست؟!!
با سپاس

پاسخ دادن
    اسفند ۲۵, ۱۳۹۱ @ ۱۰:۱۴ ب.ظ

    مشکلم برطرف شد 🙂

    پاسخ دادن
      کامران
      شهریور ۱۴, ۱۳۹۳ @ ۱۱:۰۲ ق.ظ

      سلام میخواستم بگم چطوری درست کردی , همون کلیک میکنم به صفحه ارور ۴۰۴ میره , میشه بگی
      مشکل از کجاست؟!!

      ممنونم میشم

      پاسخ دادن
اسفند ۲۶, ۱۳۹۱ @ ۷:۰۸ ب.ظ

لطفا اسکریپت رو کامل تر کنین مثلا کاربر بتونه خودش اسمی برای لینک ها بذاره و اخطار سیستم به صورت جی کوئری همراه عکس نمایش داد ه بشه
با سپاس

پاسخ دادن
    سعید
    اسفند ۲۷, ۱۳۹۱ @ ۱۰:۴۸ ق.ظ

    سلام
    این پست بیشتر جنبه آموزشی داره که نشون میده سایتهای کوتاه کننده لینک چطور کار میکنن.
    اگر اسکریپت کامل تری میخواین یا باید خودتون دست به کار بشین یا از اسکریپت های آماده ای که هست استفاده کنید

    پاسخ دادن
فروردین ۱, ۱۳۹۲ @ ۲:۳۹ ب.ظ

سلام
چرا وقتی اسکریپت لینک ها رو کوتاه میکنه تاریخ و زمانش تو دیتابیس نمایش داده نمیشه؟!
‘۰۰۰۰-۰۰-۰۰ ۰۰:۰۰:۰۰’
لطفا راهنماییم کنید
با سپاس

پاسخ دادن
    سعید
    فروردین ۱۱, ۱۳۹۲ @ ۳:۲۰ ب.ظ

    توی این اسکریپتی که گذاشتم چنین مشکلی برای من پیش نیومد.احتمالا یه جا اشتباه کردید.
    دقت کنید ببینید که آیا زمان هم در دیتابیس اضافه میشه یا خیر؟

    پاسخ دادن
    شهریور ۹, ۱۳۹۳ @ ۱:۴۹ ق.ظ

    دوست عزیز! فرمت date را در includes/UrlShortener.php بصورت (“date(“Y-m-d اصلاح کنید درست میشه. موفق باشید.

    پاسخ دادن
      آبان ۵, ۱۳۹۳ @ ۱:۴۵ ق.ظ

      درود !
      برای رفع این مشکل باید تابع data رو به شکل زیر تغییر داد تا تاریخ و ساعت کامل رو بدون هیچ مشکلی در دیتابیس ذخیره کنه :

      date(‘Y-m-d,H:i:s’)

      پاسخ دادن
بهمن ۲۶, ۱۳۹۲ @ ۳:۵۵ ب.ظ

مقاله کامل و جامعی بود

پاسخ دادن
آذر ۲۰, ۱۳۹۳ @ ۹:۵۵ ب.ظ

جالب بود – فقط من در مورد ساخت دیتا بیس مقداری مشکل داشتم کاش بیشتر توضیح میدادید .
ممنون

پاسخ دادن
علی
اردیبهشت ۱۵, ۱۳۹۴ @ ۱۲:۰۴ ب.ظ

سلام
قبلا از همین اسکریپت استفاده میکردم،بیش از ۳۶۰۰ تا لینک رو کوتاه کرد ولی الان از اسکریپت premium url shortener دارم استفاده میکنم که دیتابیسش جدول های بیشتری داره… چطور میتونم از دیتابیس قبلی هم تو اسکریپت premium url shortener استفاده کنم؟
با سپاس

پاسخ دادن
امیر
مهر ۱۶, ۱۳۹۴ @ ۱۰:۴۹ ق.ظ

۴۰۴ میخوره که
هر لینکی که کوتاه میکنی ۴۰۴ میخوره
چرا ؟
دوستان دیگه هم این مشکل رو داشتند

پاسخ دادن

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *


*