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

ژانویه 4, 2013 توسط : سعید

سلام

به احتمال زیاد تا به حال به سایتهایی برخوردید که یک لینک بزرگ میگیرن و به یک لینک کوچیک تبدیلش میکنن.سایتهایی مثل 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 که در زیر به توضیح کلاس میپردازیم :

این کلاس 6 متد داره و از کتابخانه 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 مورد نظر انتقال میدیم .در صورتی که کد کوتاه در دیتابیس وجود نداشته باشه صفحه 404 به کاربر نمایش داده میشه.

بعد از ایجاد فایل 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

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

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

موفق باشید

ژانویه 5, 2013 @ 1:48 ق.ظ

خیلی هم عالی 🙂

پاسخ
ژانویه 5, 2013 @ 4:32 ب.ظ

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

پاسخ
فوریه 28, 2013 @ 9:30 ب.ظ

عالی بود

پاسخ
Ali Yaghobi
مارس 13, 2013 @ 5:57 ب.ظ

خیلی خوب بود.

پاسخ
Ali Yaghobi
مارس 14, 2013 @ 11:14 ق.ظ

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

پاسخ
    سعید
    مارس 14, 2013 @ 3:09 ب.ظ

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

    موفق باشید

    پاسخ
علی
مارس 14, 2013 @ 3:17 ب.ظ

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

پاسخ
مارس 14, 2013 @ 11:27 ب.ظ

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

پاسخ
    مارس 15, 2013 @ 10:14 ب.ظ

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

    پاسخ
      کامران
      سپتامبر 5, 2014 @ 11:02 ق.ظ

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

      ممنونم میشم

      پاسخ
مارس 16, 2013 @ 7:08 ب.ظ

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

پاسخ
    سعید
    مارس 17, 2013 @ 10:48 ق.ظ

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

    پاسخ
مارس 21, 2013 @ 2:39 ب.ظ

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

پاسخ
    سعید
    مارس 31, 2013 @ 3:20 ب.ظ

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

    پاسخ
    آگوست 31, 2014 @ 1:49 ق.ظ

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

    پاسخ
      اکتبر 27, 2014 @ 1:45 ق.ظ

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

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

      پاسخ
فوریه 15, 2014 @ 3:55 ب.ظ

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

پاسخ
دسامبر 11, 2014 @ 9:55 ب.ظ

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

پاسخ
علی
می 5, 2015 @ 12:04 ب.ظ

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

پاسخ
امیر
اکتبر 8, 2015 @ 10:49 ق.ظ

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

پاسخ

دیدگاهتان را بنویسید

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


*