PDA

View Full Version : رگولار اکسپرشن و تشکیلات برای ولیدیشن نام کاربری



eshpilen
شنبه 22 مرداد 1390, 19:04 عصر
فرض کنید ما یه سیستم ثبت نام داریم. میخوایم محدودیت های لازم در انتخاب نام کاربری رو اعمال کنیم.
برای شروع کار به رگولار اکسپرشن این مثال توجه کنید:

<?php

if(isset($_POST['input'])) {
$input=$_POST['input'];
$re="/^([\s\x{0621}-\x{063A}\x{0640}-\x{0691}\x{0698}-\x{06D2}]|[a-zA-Z0-9_-])*$/u";
if(preg_match($re, $input)) echo 'Acceptable.';
else echo 'Not acceptable!';
}

?>

<html>
<body>
<form method="post" action="">
<input type="text" name="input">
<input type="submit" value="submit">
</form>
</body>
</html>
این رگولار اکسپرشن حاوی تمامی کاراکترهای الفبای فارسی + تمامی حروف الفبای انگلیسی + اعداد + خط فاصله و آندرلاین و Space میشه. البته درمورد فارسی اعراب رو هم شامل میشه.

این رگولار اکسپرشن پایه و ساده ای هست و برای چیزی مثل نام کاربری، کامل نیست. مثلا با این رگولار اکسپرشن کاربر میتونه از چنتا فاصله بجای نام کاربری استفاده کنه، یا میشه دو نام کاربری در سیستم ثبت کرد که در تعداد فاصله بین حروف تفاوت دارن اما ظاهرشون موقع نمایش یکسان هست. اجازه دادن اعراب هم به همین شکل بعلت مشکل بودن تشخیص جزییات نمایشی میتونه مشکل ساز باشه (یعنی کاربران میتونن با جعل هویت بر اساس شباهت ظاهری، کاربران دیگر رو گول بزنن).

خب میتونید رگولار اکسپرشن یا هر سیستم ولیدیشن پیشنهادی که دارید رو در این ارتباط مطرح کنید.
بنظر شما انتخاب نام کاربری باید چه محدودیت هایی داشته باشه؟

بنده فکر میکنم باید امکان استفاده از اعراب رو حذف کنیم.
بعد نام کاربری نتونه فقط از فاصله تشکیل شده باشه.
استفاده از فاصله در ابتدا و انتهای نام کاربری مجاز نباشه (شاید لازم باشه درمورد آندرلاین هم این محدودیت رو بذاریم - چون در لینک ها تشخیص اون از آندرلاین مربوط به لینک دشواره).
بعد نشه در نام کاربری از دو یا بیشتر کاراکتر فاصله بصورت متوالی استفاده کرد. چون به این شکل دو کاربر میتونن نام کاربری های متفاوتی داشته باشن که در مرورگر به یک شکل نمایش داده میشن؛ چون میدونید که در HTML بیش از یک فاصله بصورت یک فاصله نشون داده میشه.
بعد مثلا یه چیزایی مثل فاصلهء مجازی (که با شیفت+فاصله در بعضی کیبوردها و کنترل+شیفت+2 در بعضی کیبوردها تایپ میشه) رو هم باید حواسمون باشه جزو کاراکترهای مجاز نباشه، چون اونم اصلا دیده نمیشه.

حالا باید ببینیم میشه همهء این محدودیت ها رو در یک رگولار اکسپرشن تعبیه کرد یا اینکه باید سیستم ولیدیشن ترکیبی و چند مرحله ای داشته باشیم.

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

alismith
شنبه 22 مرداد 1390, 20:18 عصر
سلام

آقا من میگم نام کاربری فقط شامل حروف باشه بهتره ، حالا لطف کنیم عدد هم بذاریم دیگه بسه ، بدون هیچ فضای خالی و....



راستی کسی الگوریتمی چیزی سراغ نداره که شباهت بیش از حد بین دو نام کاربری رو تشخیص بده؟

این تابع کارش مقایسه بین دوتا مثلا کلمه هست
http://php.net/manual/en/function.levenshtein.php

اگربرابر باشن مقدار 0 و اگر شباهت کم باشه به میزان اختلاف عدد بزرگتر میشه


موفق باشید

eshpilen
شنبه 22 مرداد 1390, 22:55 عصر
سلام
آقا من میگم نام کاربری فقط شامل حروف باشه بهتره ، حالا لطف کنیم عدد هم بذاریم دیگه بسه ، بدون هیچ فضای خالی و....

بنظرم بهتره فاصله باشه. مثلا طرف میخواد نام و نام خانوادگی خودش رو بذاره بالاخره باید اونا رو از هم جدا کنه یا نه؟
همون محدودیت یک فاصله پشت سرهم کفایت میکنه از نظر امنیتی.
البته آندرلاین رو کلا از کاراکترهای ممکن حذف کردم چون در لینک ها تشخیصش از آندرلاین خود لینک مشکل هست.
عددهای فارسی رو هم حذف کردم چون بنظرم در ویندوز اکثرا اعداد فارسی رو به شکل انگلیسی درج میکنه و یا نشون میده، بنابراین مشکل عدم تفاوت بصری بین اعداد فارسی و انگلیسی پیش میاد.

ولیدیشنی که الان میذارم به اینصورته:
حروف فارسی، حروف انگلیسی، اعداد انگلیسی، خط فاصله بدون تکرار پشت سر هم، فاصله بدون تکرار پشت سرهم.



این تابع کارش مقایسه بین دوتا مثلا کلمه هست
http://php.net/manual/en/function.levenshtein.php

اگربرابر باشن مقدار 0 و اگر شباهت کم باشه به میزان اختلاف عدد بزرگتر میشهخیلی ممنون. ولی اونطور که الان خوندم الگوریتمش بدرد کار ما نمیخوره، چون صرفا بر اساس تعداد جابجایی های حروف هست. به این شکل مثلا hamid1 با hamid2 یا hamid شباهت زیادی خواهد داشت، درحالیکه نمیشه اینا رو بیش از حد شبیه هم دونست و غیرمجاز اعلام کرد. منظور من بیشتر مواردی بود که از نظر بصری تشخیص اونها در صفحات وب خیلی دشواره؛ ولی فکر میکنم الان باوجود محدودیت هایی که وضع کردیم تا حد زیادی جلوی این مشکل گرفته بشه. البته بخاطر دوتا بودن و شباهت بعضی حروف مثل «ک» و «ی» عربی و فارسی بازم یه مقدار مشکل وجود داره.

eshpilen
شنبه 22 مرداد 1390, 22:58 عصر
دوستان این رو ببینید و تست کنید و اگر نقص و ایرادی داشت یا نظر و پیشنهاد و انتقادی داشتید بگید:

<?php

header('Content-Type: text/html; charset=utf-8');

function utf8_strlen($string) {
$utf8_char_pattern='/[\x09\x0A\x0D\x20-\x7E]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2}/';
$results_arr=array();
preg_match_all($utf8_char_pattern, $string, $results_arr);
return count($results_arr[0]);
}

echo '<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
</head>
<body>
<center>';

$min_length=1;
$max_length=30;

if(isset($_POST['input'])) {
$input=$_POST['input'];
$input=str_replace('ي', 'ی', $input);
$input=str_replace('ك', 'ک', $input);

$length_error=false;
if(utf8_strlen($input)<$min_length) {
echo 'حداقل طول باید';
echo " $min_length ";
echo 'کاراکتر باشد';
echo '<br>';
$length_error=true;
}
else if (utf8_strlen($input)>$max_length) {
echo 'حداکثر طول باید';
echo " $max_length ";
echo 'کاراکتر باشد';
echo '<br>';
$length_error=true;
}

$permitted_chars="/^([\s\x{067E}\x{0622}\x{0627}\x{0628}\x{062A}-\x{063A}\x{0641}-\x{064A}\x{0698}\x{06A9}\x{06AF}\x{06C1}\x{06CC}]|[a-zA-Z0-9-])*$/u";
$illegal1="/^\s+/";
$illegal2="/\s+$/";
$illegal3="/\s{2}/";
$illegal4="/-{2}/";
if(preg_match($permitted_chars, $input)) {
if(!preg_match($illegal1, $input)) {
if(!preg_match($illegal2, $input)) {
if(!preg_match($illegal3, $input)) {
if(!preg_match($illegal4, $input)) {
if(!$length_error) echo 'قابل قبول';
}
else echo 'غیرقابل قبول - بیش از یک کاراکتر خط فاصله پشت سرهم غیرمجاز است';
}
else echo 'غیرقابل قبول - بیش از یک کاراکتر فاصله پشت سرهم غیرمجاز است';
}
else echo 'غیرقابل قبول - کاربرد کاراکتر فاصله در انتها غیرمجاز است';
}
else echo 'غیرقابل قبول - کاربرد کاراکتر فاصله در ابتدا غیرمجاز است';
}
else {
echo 'غیرقابل قبول - کاراکترهای غیرمجاز', '';
echo 'کاراکترهای مجاز در نام کاربری: حروف فارسی، حروف انگلیسی، اعداد انگلیسی، خط فاصله بدون تکرار پشت سر هم، فاصله بدون تکرار پشت سرهم';
}

}

?>

<form method="post" action="">
<input type="text" name="input">
<input type="submit" value="submit">
</form>
<script>
<?php
if($input) {
if(!get_magic_quotes_gpc()) $input=addslashes($input);
echo "document.forms[0].input.value=\"$input\";\n";
}
?>
</script>
</center>
</body>
</html>
محدودیتهای وضع شده که چک میشن به این شرح هستند:
حروف فارسی (بدون اعراب)، حروف انگلیسی، اعداد انگلیسی، خط فاصله بدون تکرار پشت سر هم، فاصله بدون تکرار پشت سرهم.
ضمنا حداقل طول نام کاربری 1 کاراکتر و حداکثر طول 30 کاراکتر تعیین شده، اما به این معنی نیست که این مقادیر برای تمام یا بیشتر کاربردها مناسب هستن. این مقدارها بیشتر جهت تست راحت و کامل برنامه درنظر گرفته شدن.

eshpilen
شنبه 22 مرداد 1390, 23:14 عصر
البته بخاطر دوتا بودن و شباهت بعضی حروف مثل «ک» و «ی» عربی و فارسی بازم یه مقدار مشکل وجود داره. الان یه راه حل برای این مورد بنظرم رسید که میتونیم نوع عربی و فارسی این حروف رو یکی فرض کنیم و مثلا موقع چک کردن با دیتابیس که آیا نام کاربری مشابهی وجود داره یا نه اگر نام کاربری با مشابه این حروف هم موجود بود از ثبت نام جلوگیری بشه.
یا یه راه دیگه و ساده تر اینکه میتونیم موقع ثبت نام کاربر، نوع عربی این حروف رو به نوع فارسی تبدیل کنیم و بعد در دیتابیس درج کنیم. موقع لاگین هم طبیعتا باید حروف عربی رو با فارسی جایگزین کنیم. ضمنا اینطوری اگر کاربر از یک کیبورد به استاندارد کیبورد دیگری بره (مثلا بخاطر تفاوت بین Keyboard layout سیستم عاملهای مختلف که شخصا دیدم وجود داره)، مشکلی در تایپ نام کاربری خودش پیدا نمیکنه.

ویرایش:
تبدیل حروف «ک» و «ی» عربی انجام و نمونه کد بالا آپدیت شد. کسی کاراکتر دیگری هم سراغ داره که نیاز به تبدیل داشته باشه؟ (یعنی دو نوع عربی و فارسی داشته باشه که روی کیبوردها قابل تایپ باشن).

alismith
یک شنبه 23 مرداد 1390, 00:31 صبح
سلام
آقا من از شما یک انتقاد دارم آخه چه معنی داره شما اینطوری قوی کار می کنید و به فکر امنیت سایت هستید :چشمک:

آقا شوخی کردم خیلی ممنون واقعا خیلی جالب و قوی کار کردید فقط در رابطه با عربی کاراکتر ت عربی چی اون مهم نیست؟ می دونم شباهت نداره ولی میگم به فارسی تبدیل نکنیم ، مثلا در جستجوی کاربر یا کارای دیگه یک شکل باشه (هم فارسی باشن) بهتر نیست؟ البته شایدم مهم نباشه ، دیدم شما خیلی دقیقی منم دارم الکی گیر میدم :چشمک:

خیلی ممنون

موفق باشید

eshpilen
یک شنبه 23 مرداد 1390, 09:03 صبح
فقط در رابطه با عربی کاراکتر ت عربی چی اون مهم نیست؟

کدوم ت؟
بنده کاراکترها رو با استفاده از نرم افزار Character Map ویندوز بررسی کردم و کدهاشون رو درآوردم، و بنظرم در رگولار اکسپرشنی که بنده گذاشتم فقط یک «ت» بیشتر نداریم. اون یکی ت هایی که دیدم (در فونت Arial) شکلهای عجق وجقی داشتن که فکر نمیکردم در Keyboard layout های استاندارد مورد استفادهء ملت جایی داشته باشن، بخاطر همین اونا رو جزو کاراکترهای قابل قبول قرار ندادم. حالا شما هم منظورتون هرکدوم هست میتونید به برنامه بدید ببینید قبول میکنه یا نه و آیا بنظرتون باید قبول بکنه یا نه؟
میتونید با استفاده از Character Map ویندوز ت مورد نظر رو پیدا و کپی کنید.

Metal Gear Solid
یک شنبه 23 مرداد 1390, 09:34 صبح
برای اینکه بشه از کاراکترهای &nbsp; جلوگیری کرد میشه کد این عدد رو در داخل عبارت منظم نوشت
آقای eshpilen به شما پیشنهاد میکنم در بکار بردن ! دقت کنید. چون در مواقعی که مدار کوتاه رخ بده ممکنه برنامه مطابق با چیزی که شما نوشتید کار نکنه
البته اینجا OR ندارید اما به کار بردن OR یا || با علامت ! یا بدون اون نیاز به دقت زیادی داره.

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

Metal Gear Solid
یک شنبه 23 مرداد 1390, 09:46 صبح
من کد شما رو تست کردم واقعاً بی نقص کار میکنه. فاصله در ابتدا، انتها، دو فاصله پشت سر هم، همه جلوگیری شده
خودتون ایرادی در این کد میبینید؟
به نظر من که کامله. بهترین عبارت منظمی که فارسی رو ساپورت کنه و تا به حال دیدم به نظرم همینه!!!

Metal Gear Solid
یک شنبه 23 مرداد 1390, 09:50 صبح
به نظر من بهتره برای هر بخشی یک الگو طراحی کرد.
برای نام های کاربری یک الگو - شامل تک کوتیشن و دابل کوتیشن نشه.
برای عباراتی که از متدهای POST و یا GET گرفته میشن یک الگو - شامل تک کوتیشن و دابل کوتیشن و هر کاراکتری که به URL اسیب میزنه نشه
برای متن هایی نظیر عنوان یک ارسال یا تاپیک یا مطلب ، اسامی فیلم یا هر چیز دیگه که ممکنه حاوی : ' " ; و غیره بشه هم یک الگو
برای متن های چند خطی یا توضیحات که با ادیتورها نوشته و ارسال میشن هم یه الگو
اشتباهی که من قبلاً میکردم و برای تمامی این موارد از یک الگو استفاده میکردم. البته دوران جوانی و کم تجربگی :D

eshpilen
یک شنبه 23 مرداد 1390, 09:58 صبح
برای اینکه بشه از کاراکترهای &nbsp; جلوگیری کرد میشه کد این عدد رو در داخل عبارت منظم نوشترگولار اکسپرشن ما اجازهء چنین کاراکترهایی رو نمیده. چون & و ; هیچکدام جزو کاراکترهای مجاز نیستن. اگر هم منظورتون کد کاراکتر خاصی هست بازم رگولار اکسپرشن ما محدودتر از اون حرفاست که اجازه بده. بطور مثال فاصلهء مجازی (یا اسم دیگش فاصله با پهنای صفر) رو قبول نمیکنه.
ضمنا یادتون نره حتی موقع درج نام کاربری کاربر در صفحه هم باید از htmlspecialchars استفاده کرد. به این صورت اگر نام کاربری حاوی چیزی مثل &nbsp; باشه، بعنوان کد HTML تفسیر و اجرا نمیشه و دقیقا به همون شکلی که تایپ شده نمایش داده میشه.


آقای eshpilen به شما پیشنهاد میکنم در بکار بردن ! دقت کنید. چون در مواقعی که مدار کوتاه رخ بده ممکنه برنامه مطابق با چیزی که شما نوشتید کار نکنه
البته اینجا OR ندارید اما به کار بردن OR یا || با علامت ! یا بدون اون نیاز به دقت زیادی داره.توجه نشدم منظور شما چیه! رگولار اکسپرشن بنده مشکلی داره؟


در رابطه با اسکریپت هایی که بالا نوشتید. مگه با نوشتن یک trim زمانی که همه چیز اوکی باشه نمیشه از کاراکترهای سفید اضافه جلوگیری کرد؟ اونطور که در منوال نوشته trim فقط کاراکترهای سفید رو از ابتدا و انتهای رشته حذف میکنه. اما مثلا در داخل رشته بین دو حرف یا کلمه اگر این کاراکترها باشن کاری انجام نمیده. ما میخوایم فرضا اگر دوتا کاراکتر فاصله پشت سرهم در بین دو حرف وجود داشتن ولیدیشن Fail بشه.
دوما با trim همینطوری سرخود اگر ورودی کاربر رو تغییر بدیم و هیچ خطا و هشداری ندیم بنظر بنده از نظر اصولی جالب نیست. بنظر من بهتره به کاربر خطا بدیم و کاملا متوجه بشه اشکال کجا بوده و خودش دیتای خودش رو اصلاح کنه. اگر کاربر در ابتدا یا انتها کاراکتر فاصله تایپ کرده ممکنه فکر خاصی کرده باشه (احتمالا فکر کرده اون فاصله ها هم جزو نام کاربری محسوب میشن) و احتمال تصادفی بودن این امر زیاد نیست که ما همینطوری trim کنیم و کاربر هم هیچ متوجه این موضوع نشه.

eshpilen
یک شنبه 23 مرداد 1390, 10:10 صبح
به نظر من بهتره برای هر بخشی یک الگو طراحی کرد.
برای نام های کاربری یک الگو - شامل تک کوتیشن و دابل کوتیشن نشه.
برای عباراتی که از متدهای POST و یا GET گرفته میشن یک الگو - شامل تک کوتیشن و دابل کوتیشن و هر کاراکتری که به URL اسیب میزنه نشه
برای متن هایی نظیر عنوان یک ارسال یا تاپیک یا مطلب ، اسامی فیلم یا هر چیز دیگه که ممکنه حاوی : ' " ; و غیره بشه هم یک الگو
برای متن های چند خطی یا توضیحات که با ادیتورها نوشته و ارسال میشن هم یه الگو
اشتباهی که من قبلاً میکردم و برای تمامی این موارد از یک الگو استفاده میکردم. البته دوران جوانی و کم تجربگی :D
ایجاد معیار و الگوی کلی برای اینها بسیار دشوار یا غیرممکن هست.
برنامه نویس باید خودش دانش و بینش کافی داشته باشه و در هر موردی محدودیت و ولیدیشن صحیح رو طراحی کنه. مثل نام کاربری که در این تاپیک روش کار کردیم.
بطور مثال اجازه ندادن کوتیشن در POST و اینها بنظر بنده کاملا غیر منطقی هست. کوتیشن در خیلی متنها باید وجود داشته باشه.
یوقت آدم ممکنه برنامهء وبی بنویسه که حتی دیتای باینری رو بعنوان ورودی میگیره. این امر لزوما غیرممکن نیست! و روی یک دیتای باینری هیچ محدودیتی نمیشه گذاشت. تنها کاری که باید کرد Escape کردن موقع درج در کوئری و اینطور چیزهاست.
یا مثلا همینطور درمورد پسورد بنده معتقد به عدم محدودیت یا محدودیت خیلی کمی هستم. چون پسورد جایی نمایش داده نمیشه و به کاربران و مرورگرهای دیگه نمیتونه حمله کنه و از طرف دیگه ممکنه کسی بخواد بخاطر امنیت بیشتر از کاراکترهای خاصی که شاید حتی نشه با کیبورد براحتی تایپشون کرد در پسورد خودش استفاده کنه. البته اینم یک نظر هست و مثل هر نظر دیگری میتونه کم و بیش اشتباه باشه! شاید موارد دیگری رو هم باید مد نظر قرار بدیم که ازشون اطلاع نداریم.

Metal Gear Solid
یک شنبه 23 مرداد 1390, 10:10 صبح
الان تست کردم و یک مشکل خیلی ریز در برنامه وجود داره.
اول کار و بعد از isset اگر یک !empty اضافه کنید درست میشه. چون رشته ی خالی رو هم قابل قبول میزنه.

------

البته منظور من از GET , POST این بود که یه جوری بشه از علامات ' " در انتهای آدرس جلوگیری کرد. یکی از روشها ی گرفتن خطا از صفحات همینه که یک تک کوتییشن آخر آدرس میزنن تا ببین برنامه با خطا رو به رو میشه یا نه. البته این به تبهر برنامه نویس برمیگرده اما همین تبهر رو میشه در یک تابع یا متد خلاصه کرد و جلوی این دست کارهارو گرفت. منظورم اون POST یا GET که همه ی اطلاعات رو از فرمی به فرمی دیگه ارسال میکنیم نبود!

eshpilen
یک شنبه 23 مرداد 1390, 10:33 صبح
رشته ی خالی رو هم قابل قبول میزنه.بله چک کردن طول رشته رو آگاهانه در این سیستم ولیدیشن قرار ندادم. چون بنده همیشه بخش چک کردن حداقل و حداکثر طول رو یه بخش مجزا میدونم که باید با توجه به هر موردی تعیین بشه. مثلا در بعضی موارد حتی رشتهء خالی هم میتونه قابل قبول باشه (البته نه عمدتا برای نام کاربری!). بهرحال نام کاربری هم ممکنه نیاز به حداقل طول بیشتر از یک کاراکتر داشته باشه.
البته احتمالا دست آخر که کد نهایی رو گذاشتم احتمالا باید این چک رو هم توش میذاشتم تا کد کامل باشه.
اینکه گفتی خوب شد، چون بعضی ها شاید فکر کنن این کد مطلقا کامل و آمادهء استفاده هست. حالا بعد یه چیزی بهش اضافه میکنم و کدش رو اصلاح میکنم.


البته منظور من از GET , POST این بود که یه جوری بشه از علامات ' " در انتهای آدرس جلوگیری کرد. یکی از روشها ی گرفتن خطا از صفحات همینه که یک تک کوتییشن آخر آدرس میزنن تا ببین برنامه با خطا رو به رو میشه یا نه.تاجاییکه میدونم این برای چک کردن امکان SQL Injection هست.
بنظر بنده ضرورتی نداره و منطقی نیست جلوی این علامتها رو بگیریم.
برنامه باید بصورت درونی در برابر SQL Injection امن باشه. وگرنه راه و ترفند برای پی بردن به ضعفهای برنامه، بنظرم زیادتر از این باشه.
بنظر من ارزش نداره آدم وقت و انرژی روی ترفندهای غیرمستقیم و ناقص بذاره و بیخود برنامه رو پیچیده و نامنعطف بکنه که ممکنه بعدا جایی موجب دردسر یا باگی بشن.

eshpilen
یک شنبه 23 مرداد 1390, 11:08 صبح
کد چک کردن حداقل و حداکثر طول رو هم به برنامه اضافه کردم.
کدش در همون پست قبلی آپدیت شد.

رضا قربانی
یک شنبه 23 مرداد 1390, 14:51 عصر
حالا که انقدر زحمت کشیدی یه captcha هم می نداختی روش .
خوب بود که نام input هم کد شده میذاشتی .
اگر isset یا empty هم می گذاشتی خوب بود چون روی سرعت تاثیر داره ، یعنی از چیزهای کوچیک جلوگیری می کنه و نمیذاره دیگه دستورات if اجرا بشه و این روی سرعت خیلی تاثیر داره و هم می تونستی به جای if از case استفاده کنید .
و حجم کد نویسی رو در کل زیاد می کنی
مثلا :

echo 'حداقل طول باید';
echo " $min_length ";
echo 'کاراکتر باشد';
echo '<br>';
می تونستی اینطوری هم بنویسی :


echo 'حداقل طول باید'. $min_length.' کاراکتر باشد <br>';

در کل اسکریپت بدون نقص از جانب علم منه .

موفق باشید

eshpilen
یک شنبه 23 مرداد 1390, 21:06 عصر
حالا که انقدر زحمت کشیدی یه captcha هم می نداختی روش .این که یه پروژهء کامل نیست. فقط دربارهء ولیدیشن نام کاربری هست.


خوب بود که نام input هم کد شده میذاشتی .بله؟! متوجه نشدم منظورت چیه.


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


اگر isset یا empty هم می گذاشتی خوب بود چون روی سرعت تاثیر داره ، یعنی از چیزهای کوچیک جلوگیری می کنه و نمیذاره دیگه دستورات if اجرا بشه و این روی سرعت خیلی تاثیر داره و هم می تونستی به جای if از case استفاده کنید .بهرصورت باید حداقل و حداکثر طول چک بشن. کلا اونقدرها هم توی سرعت تاثیر نداره. در عمل هیچی! اینطور بهینه سازیها جاهایی که ترافیک واقعا زیادی هست بصورت همزمان شاید به زور خودشون رو نشون بدن، نه توی بخش ثبت نام یه سایت معمولی.
ضمنا اگر بهینه سازی میخوای بذار خودم بهت بگم! اون چهارتا رگولار اکسپرشن آخر یعنی اونایی که توی اسمشون illegal هست رو میشه بدون رگولار اکسپرشن هم درست کرد (یعنی بجای preg_match از strpos و امثالهم استفاده کرد).ولی شکل رگولار اکسپرشن ساده تر و خواناتره. و این فاکتورها رو در برنامه هیچوقت دست کم نگیر. جایی که عملا مشکل پرفورمنس دیده نمیشه، این فاکتورها میتونن مهمتر باشن.کلا سعی کن زیاد روی بهینه سازی وسواسی نباشی. نه اینکه بخوام از خودم تعریف کنم، اما چیزایی که میگی رو بنده سالها پیش یاد گرفتم و در این زمینه اگر از شما بینش بیشتری نداشته باشم کمتر هم ندارم. ولی بهینه سازی های جزیی به این شکل امروزه در بیشتر کاربردها عملا ارزش وقت و انرژی ای که صرف میشه و در مقابل خیلی وقتا خوانایی برنامه رو کم میکنن و احتمال باگ رو بالا میبرن رو ندارن. جایی باید بهینه سازی کرد که واقعا تاثیر گنده ای داره یا در عمل مشکل پرفورمنس دیده میشه. بنده یکی دوتا تاپیک در این مورد هم دارم اگر نخوندی پیدا کن و بخون (مثلا نقل نظر یکی دوتا از برنامه نویسان حرفه ای توش هست - حرف خودم به تنهایی نیست).
البته آدم باید دانش و مهارت در بهینه سازی داشته باشه تا هروقت نیاز شد استفاده کنه، اما نه اینکه روی هر برنامه و کدی سعی کنه تمام بهینه سازیهایی رو که ممکن هست اعمال کنه. یه بهینه سازی بکنی یه صفحهء PHP بجای 0.2 ثانیه در 0.1 ثانیه اجرا بشه، در بیشتر کاربردها و جاها هیچ اهمیتی نداره و عملا وقت و انرژی خودت رو تلف کردی و احتمالا به خوانایی برنامه هم صدمه زدی. راههای ساده و سرراست (از نظر کدنویسی) اکثرا با راندمان کافی کار میکنن. میگم کافی، نه بالاترین راندمان ممکن.

ضمنا این کد برای نشون دادن و تست الگوریتم بوده و درش سادگی و خوانایی اولویت اول رو داره. هیچوقت یک الگوریتم آموزشی یا مورد ارزیابی رو نباید زیادی پیچیده کرد تا تمرکز از اصل مطلب روی پیچیدگی های غیرضروری متمرکز بشه و وقت و انرژی خودت و دیگران روی چنین مواردی هدر بره، مگر اینکه بحث روی بهینه سازی اون الگوریتم باشه.

خلاصه از ما گفتن بود. ولی این نظرات همه بر اساس دانش و تجربه هست و تحلیل منطقی اونا رو کاملا تایید میکنه.
حالا اگر بنظرت درست هست بگو درست میگی، اگر درست نیست بهتره دلیل و سند درست و حسابی بیاری برای مخالفت خودت.
فراموش نکن روی بهینه سازی خیلی میشه کار کرد. هزار نوع بهینه سازی داریم.
همین برنامه رو اگر من میخواستم تا حداکثر ممکن بهینه سازی کنم کلی بیشتر طول میکشد تا بنویسم و تست کنم و انرژی خیلی زیادتری میخواست تا باهاش سر و کله بزنم و باگ هاش رو شناسایی و اصلاح کنم. این کار اصلا منطقی نیست. نه برای این کد و تست و تحلیل الگوریتم، در خیلی جاهای دیگر هم منطقی نیست.
حتی درمورد برنامه هایی که عملا مشکل پرفورمنس دارن نمیان همهء بخشهای کد و الگوریتم رو بهینه سازی کنن، بلکه میان و تنگه های اصلی (Bottleneck) رو شناسایی و بهینه سازی میکنن. بهینه سازیهای جزیی در بیشتر موارد ارزشی ندارن و پارامترهای مهمتر برنامه مثل خوانایی و سادگی رو هم مخدوش میکنن.

مثلا بعضیا میگن برای درج متغییرهای PHP در رشته ها از روش Concatenation استفاده کنید، اما من فکر نمیکنم اجباری به این کار باشه، چون خیلی جاها افزایش پرفورمنس به این خاطر اصلا زیاد نیست و از طرف دیگه در خیلی جاها خوانایی روشی که متغییر رو مستقیما توی رشته میذاری (اسمش چی بود؟ interpolation؟) بیشتر هست و نیاز به تایپ و دقت کمتری داره. مثلا در همین برنامه من کدی به این شکل دارم:

echo " $min_length ";
اگر بخوام اون رو به روش Concatenation بنویسم اینطور میشه:


echo ' '.$min_length.' ';
اختلاف سرعت این دو شکل در این مورد خاص که رشتهء خیلی ساده و کوتاهی داریم درحد کمی هست، و این هیچوقت در عمل احساس نخواهد شد.
من شکل اول رو موقع نوشتن کد ساده تر و کوتاهتر دیدم و ضمنا بنظرم مقداری خواناتر هم هست (گرچه نه خیلی زیاد؛ چون این مورد خیلی ساده ای هست و زیاد نشون نمیده)، بخاطر همین ازش استفاده کردم. حالا شما میگی بخاطر بهینه سازی و بدست آوردن یک زمان خیلی ناچیز که هیچوقت کسی متوجه اون نخواهد شد، بیام و از فرم دوم استفاده کنم؟ یه وقت آدم یه نرم افزار فروم مینویسه که میدونه ترافیک همزمان زیاد رو باید جواب بده، شاید از این کارها بکنه، اونم بیشتر برای رشته های پیچیده و حجیم، ولی نه برای یه سایت و برنامهء عادی و یه همچین چیزای ساده ای.

eshpilen
یک شنبه 23 مرداد 1390, 21:42 عصر
بنظر من آدم یه برنامه رو باید طوری بنویسه که براش راحتتر و سریعتر هست و به خوانایی بیشتری منجر میشه. چون هدف و اولویت اصلی کامل کردن برنامه هست و راحتی مطالعه و تغییر و گسترش اون، نه حداکثر کردن پرفورمنس اون.
بعد از اینکه الگوریتم و کارایی برنامه کامل شد و باگ نداشت، آدم میتونه بهینه سازیهای بزرگ رو روش انجام بده، تازه اونم اگر در عمل هیچ فایدهء مهمی نداشته باشه بنظر من منطقی نیست، چون این کار رو آدم هروقت نیاز بشه میتونه انجام بده.
شاید بپرسید بهینه سازی بزرگ چی میتونه باشه. خب احتمالا بهینه سازی کوئری های SQL درمورد دیتابیس های حجیم، فشرده سازی یا کاهش داده ها یا استفاده از الگوریتم بهینه سازی سرعت درمورد داده های حجیمی که باید از طریق شبکه یا اینترنت جابجا بشن، بهینه سازیهایی روی بعضی الگوریتم ها که مثلا باعث میشن تکرار حلقه های تکرار با تعداد بالا یک سوم یا نصف بشه، و خلاصه از اینطور چیزا. اینکه یه عملیات رو بجای اینکه در چند تکه و چند خط بنویسیم در یک خط ترکیب کنیم بنظر من نمیتونه یه بهینه سازی بزرگ محسوب بشه. در اینطور موارد خوانایی برنامه و راحتی ویرایش اولویت اول رو داره. ضمنا خوانایی برنامه لزوما به معنای کاهش حجم کد نیست. مثلا وقتی اسم یک متغییر رو یه چیز طولانی اما خوانا و محتوی اطلاعات زیادی میذارید، برنامه رو خواناتر کردید، اما تایپ و حجم برنامه زیاد شده. یا خیلی وقتا بهتره یه عملیات ترکیبی رو چند قطعه کنیم و در چند خط بنویسیم و حتی از متغییرهای موقتی برای نگهداری نتایج بینابینی استفاده کنیم تا خوانایی و راحتی ویرایش برنامه زیادتر بشه.

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

خود شما میبینید که همین یک چیز ساده که بخش کوچکی از مثلا یک سیستم ثبت نام هست که خودش بخشی از یک اپلیکیشن یا سایت وب هست، چقدر ریزه کاری و نیاز به الگوریتم و چک داره. اینا کارهای اصلی ما برنامه نویسان هستن، نه بهینه سازی واسهء چندرغاز سرعت و مموری.

کارهای اصلی ما برنامه نویسان اینها هستن: طراحی و پیاده سازی الگوریتم های بی نقص و Robust برای انجام عملیات اصلی برنامه (نه بهینه سازی های غیرضروری)، همچنین طراحی و پیاده سازی الگوریتم هایی برای برقراری امنیت درحد لازم، تامین پایداری برنامه، تامین امکانات مورد نیاز برنامه و در درجهء بعدی افزایش امکانات اون، نوشتن کدهای خوانا و منعطف و قابل گسترش و ماجولار، ... .
بهینه سازی های غیرضروری اولویت آخر رو دارن.
و توجه داشته باشید که بهینه سازی اغلب خیلی از موارد بالا رو مخدوش و دشوار میکنه، چون اغلب کد پیچیده تر و ناخواناتر و غیرمنعطف تر میشه.

این چیزی که بنده در این تاپیک گذاشتم تازه هنوز یه سیستم کامل و با بهترین ساختار اصولی ممکن نیست لزوما.
و مطمئن باشید در هر زمینه ای، خیلی چیزها برای مطالعه و بررسی بیشتر هست.
بجای اینکه وقت و انرژی خودتون رو روی مقایسه پرفورمنس چیزهای جزیی صرف بکنید، بهتره دانش و مهارت خودتون رو در زمینهء الگوریتم و امنیت گسترش بدید و بهتره برنامه ها رو بیشتر شیء گرا کنید، بیشتر ماجولار کنید، بیشتر منعطف کنید، ... . تازه این کارها که میگم بکنید خودش ده برابر و بیشتر از اون بهینه سازیهای جزیی که میگید هزینهء پرفورمنس اضافه میکنه، اما بازم ما این کارها رو انجام میدیم، و هیچکس نمیگه درست نیست و مثلا برنامه رو شیء گرا و ماجولار ننویسید و لایه های انتزاع لازم برای این کارها رو بهش اضافه نکنید، چون واقعا یه برنامهء شیء گرا، ماجولار، خوانا، ساده و منعطف با سرعت کافی خیلی بهتر از یه برنامه هست که این ویژگیها رو نداره یا کمتر داره اما سرعتش خیلی بیشتره.

eshpilen
یک شنبه 23 مرداد 1390, 22:19 عصر
برنامه نویسان حرفه ای میگن اصلا برنامه تا به بلوغ خودش نرسیده، کار کردن روی بهینه سازی اتلاف وقت و انرژیه. چون برنامه معمولا به سرعت تغییر میکنه و خیلی از بهینه سازیهای ما عملا از بین میرن و بارها نیاز به بازنویسی و روشهای دیگر پیدا میکنن.
ضمنا خیلی کارهای مهمتر از بهینه سازی هست.
معمولا چند نسخه و نسل از برنامه باید بگذره تا به حدی برسه که تنها کار مفید باقی مانده بهینه سازی بیشتر اون باشه.

بطور مثال شما همین سیستم رو درنظر بگیرید و فرض کنید ما یه سیستم ثبت نام درست کردیم.
حالا بجای اینکه رگولار اکسپرشن ها و کد ولیدیشن ما برای هر فیلد ثبت نام اینطور لای انبوه کدها پراکنده باشه، خیلی مفید هست که ما یک سیستم متمرکز و منسجم برای ولیدیشن طراحی کنیم. مثلا طوری باشه که رگولار اکسپرشن ها، حداقل طول، حداکثر طول هر فیلد و غیره رو در یک فایل کانفیگ مجزا از کدهای ولیدیشن ذخیره کنیم. اینطوری پیکربندی و تغییر این گزینه ها خیلی ساده تر و سریعتر میشه و برنامه یک قدم به سمت ماجولار شدن برداشته. کد ولیدیشن هم بجای اینکه چند مدل برای چند فیلد در برنامه پراکنده باشه بهتره بصورت یک سیستم تا حد ممکن هوشمند و خودکار در یک فایل مجزا که در بقیهء برنامه هرجا که نیاز اینکلود میشه قرار داشته باشه و فایل کانفیگ ولیدیشن هر بخش برنامه رو بهش بدی و خودش اون مقادیر و دستورات رو بخونه و طبق اونها فیلدهای مورد نظر رو ولیدیت کنه.
برنامه های حرفه ای رو، فریمورک های مدرن رو، کم و بیش همینطور طراحی میکنن. همه چیز به سمت ماجولار شدن و تمرکز و خوانایی برنامه در کل میره. گرچه کدها بیشتر میشن، لایه ها بیشتر میشن، و نیاز به الگوریتم ها و روشهای پیچیده تری هست، ولی چون از طرف دیگه برنامه ماجولار میشه و هر بخشی از نظر منطقی و مدیریتی و کد جدا میشه و انعطاف و گسترش پذیری بیشتری بوجود میاد، در مجموع به نفع برنامه و برنامه نویس هست. ضمنا در برنامه های بزرگ یا کارهای متعددی که از این سیستمها و اجزاء و کلاسها استفاده بشه، هزینهء اولیهء اونها براحتی جبران میشه و در مجموع کد و پیچیدگی کمتری خواهیم داشت. ولی برای برنامه های کوچیک ممکنه طراحی و نوشتن اولیهء اینا هزینه و کد زیادی بنظر بیاد.
البته بنظر بنده یا آدم باید تجربهء زیادی در این امور داشته باشه و یا برنامه رو اول بصورت ساده و موقت گسترش بده و بعد از اینکه یک بلوغ نسبی پیدا کرد و برنامه نویس احاطه و بینش و ایده های خوب و مطمئن تری پیدا کرد، بیاد و روی این مسائل کار کنه. هرچند بنده خودم یه پروژهء رجیستر و لاگین که نوشتم تونستم اون رو تاحد خوبی از همون ابتدا بصورت ماجولار و درمورد اجزای درونی برنامه بصورت شیء گرا بنویسم. خیلی هم کار سختی نیست. ولی اون برنامه رو الان باید تغییرات زیادی بدم و میتونم ایده های بیشتری داشته باشم، چون دانش و تجربم بیشتر شده.

خب تمام این کارها که میگم شما مخالفتی ندارید که انجام بشه؟
ولی میدونید همهء این کارها چقدر پرفورمنس بیشتری مصرف میکنه؟
مثلا درج پارامترهای ولیدیشن در فایلهای پیکربندی (احتمالا در قالب یک آرایهء تودرتو) که بعد بخش ولیدیتور برنامه که خودش در صفحات اصلی اینکلود میشه و فایل پیکربندی هم اینکلود یا پاس میشه و بعد باید فیلدها و پارامترهای فایل پیکربندی رو بخونه و بصورت خودکار روی اونها عملیات لازم رو انجام بده، همین کارها خودشون نیاز به کلی کد و الگوریتم بیشتر و مصرف پرفورمنس احتمالا ده ها برابر شکل Hard code شده و غیرماجولار دارن. اینا همه لایه های بیشتری هستن.
اما ما همهء این کارها رو انجام میدیم و تقریبا هیچکس جرات نمیکنه بگه این کار رو نکنید چون ده برابر بیشتر پرفورمنس مصرف میکنه! پس باید متوجه بشید که پرفورمنس واقعا اونقدرها هم مهم نیست. یعنی پرفورمنس در سیستمهای امروزی اغلب به حد بحرانی نمیرسه که اولویت اول رو پیدا کنه.
یه زمانی سیستمها خیلی ضعیف تر بودن و منابع سخت افزاری خیلی کم بود، اون زمان بخاطر صدم ثانیه زمان CPU و چند صد بایت مصرف حافظهء کمتر خودشون رو میکشتن. ولی الان اصلا اینطور نیست.
میشه گفت بخش بزرگی از از دانش و روشهای بهینه سازی هم در همون دوران اختراع شدن چون نیاز و انگیزه وجود داشت. البته بهینه سازی الان هم کاربرد داره و یک دانش و مهارت مهمه، ولی نه به شکل اون دوران در همه جا و همه نوعش و با اولویتی که همیشه جزو بالاترین اولویت ها باشه.

eAmin
دوشنبه 24 مرداد 1390, 00:24 صبح
بنظر بنده اینکه بیایم و برای هر کاراکتر غیر مجاز یک پیغام جداگانه بدیم یک خرده کار بیهوده ای است و در بعضی از موارد کلا پیشنهاد خوبی نیست. اول اینکه حجم کدهای ما بی جهت بالا میره درصورتی که می تونیم سر و ته اینکار رو با یک پیغام هم بیاریم و دوم اینکه وقت بسیار مهمه و نباید بی خودی وقت خودمون رو برای اینطور چیزها صرف کنیم. در عوض می تونیم تمامی موارد رو بصورت لیستی منظم به کاربر نشون بدیم و بگیم که این موارد رو رعایت کنه و درصورت رعایت نکردن به یک پیغام خطای مناسب اون رو به موارد گفته شده راهنمایی کنیم تا دوباره اونها رو بخونه. البته چون این تاپیک صرفا برای آموزش و بحث در مورد بکارگیری روشهای مناسب هست زیاد این موضوع ها اهمیتی نداره...
مثلن استفاده چندباره از preg_match کمی غیر عادی بنظر میرسه(البته با توجه به مواردی که بالا عرض کردم) در صورتیکه در عبارات با قائده می تونیم 4 بار فراخوانی یک تابع رو به یکبار کاهش بدیم.
در هرصورت من کدها رو کمی دستکاری کردم، گرچه رعایت موارد بهینه سازی در مراحل طراحی/توسعه و تست زیاد مهم نیست.


$permitted_chars="/^([\s\x{0622}\x{0627}\x{0628}\x{062A}-\x{063A}\x{0641}-\x{064A}\x{0698}\x{06A9}\x{06AF}\x{06C1}\x{06CC}]|[a-z0-9-])*$/iu";
$illegal = "/((^\s+|\s+$)|[\s-]{2})/";

if(preg_match($permitted_chars, $input)) {
if(!preg_match($illegal, $input)) {
if(!$length_error) echo 'قابل قبول';
} else {
echo 'غیرقابل قبول - بیش از یک کاراکتر خط فاصله پشت سرهم/ابتدا/انتها غیرمجاز است';
}
} else {
echo 'غیرقابل قبول - کاراکترهای غیرمجاز', '';
echo 'کاراکترهای مجاز در نام کاربری: حروف فارسی، حروف انگلیسی، اعداد انگلیسی، خط فاصله بدون تکرار پشت سر هم، فاصله بدون تکرار پشت سرهم';
}



اونطور که در منوال نوشته trim فقط کاراکترهای سفید رو از ابتدا و انتهای رشته حذف میکنه. اما مثلا در داخل رشته بین دو حرف یا کلمه اگر این کاراکترها باشن کاری انجام نمیده. ما میخوایم فرضا اگر دوتا کاراکتر فاصله پشت سرهم در بین دو حرف وجود داشتن ولیدیشن Fail بشه.
دوما با trim همینطوری سرخود اگر ورودی کاربر رو تغییر بدیم و هیچ خطا و هشداری ندیم بنظر بنده از نظر اصولی جالب نیست. بنظر من بهتره به کاربر خطا بدیم و کاملا متوجه بشه اشکال کجا بوده و خودش دیتای خودش رو اصلاح کنه. اگر کاربر در ابتدا یا انتها کاراکتر فاصله تایپ کرده ممکنه فکر خاصی کرده باشه (احتمالا فکر کرده اون فاصله ها هم جزو نام کاربری محسوب میشن) و احتمال تصادفی بودن این امر زیاد نیست که ما همینطوری trim کنیم و کاربر هم هیچ متوجه این موضوع نشه.
شما هم همونطور که دیگران رو تشویق می کنید که خیلی وسواس به خرج ندن، بهتره که خودتون هم اینکار رو بکنید!
در هرصورت من هنوز هم قانع نشدم، و اگر من باشم trim یکی از راههایی هست که بکار میبرم. به اینصورت الگوی ریگولار اکسپرشنی هم که نوشتیم بهینه تر میشه!

eshpilen
دوشنبه 24 مرداد 1390, 15:12 عصر
بنظر بنده اینکه بیایم و برای هر کاراکتر غیر مجاز یک پیغام جداگانه بدیم یک خرده کار بیهوده ای است و در بعضی از موارد کلا پیشنهاد خوبی نیست. اول اینکه حجم کدهای ما بی جهت بالا میره درصورتی که می تونیم سر و ته اینکار رو با یک پیغام هم بیاریم و دوم اینکه وقت بسیار مهمه و نباید بی خودی وقت خودمون رو برای اینطور چیزها صرف کنیم.

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


در عوض می تونیم تمامی موارد رو بصورت لیستی منظم به کاربر نشون بدیم و بگیم که این موارد رو رعایت کنه و درصورت رعایت نکردن به یک پیغام خطای مناسب اون رو به موارد گفته شده راهنمایی کنیم تا دوباره اونها رو بخونه.اینم میشه و ایدهء خوبیه حتی از نظر یوزرفرند بودن، ولی من میگم علاوه بر این، پیام خطای دقیق هم بتونیم بدیم بهتره از نظر یوزرفرند بودن. ضمنا همونطور که گفتم این کار به نفع خود برنامه نویس هم هست و کار چندان سختی نیست. اگر برنامه پیامهای خطای کامل و دقیق بده، برنامه نویس خودش موقع تست و توسعه سریعتر و موفق تر خواهد بود. حتی به این شکل باگهایی کشف میشن که در غیراینصورت براحتی ممکنه برنامه نویس متوجه وجود اونها نشه.





$permitted_chars="/^([\s\x{0622}\x{0627}\x{0628}\x{062A}-\x{063A}\x{0641}-\x{064A}\x{0698}\x{06A9}\x{06AF}\x{06C1}\x{06CC}]|[a-z0-9-])*$/iu";
$illegal = "/((^\s+|\s+$)|[\s-]{2})/";

if(preg_match($permitted_chars, $input)) {
if(!preg_match($illegal, $input)) {
if(!$length_error) echo 'قابل قبول';
} else {
echo 'غیرقابل قبول - بیش از یک کاراکتر خط فاصله پشت سرهم/ابتدا/انتها غیرمجاز است';
}
} else {
echo 'غیرقابل قبول - کاراکترهای غیرمجاز', '';
echo 'کاراکترهای مجاز در نام کاربری: حروف فارسی، حروف انگلیسی، اعداد انگلیسی، خط فاصله بدون تکرار پشت سر هم، فاصله بدون تکرار پشت سرهم';
}
بعد نیست، جالبه. بنده چون فکر نمیکردم بشه $ رو در جایی غیر از انتهای رگولار اکسپرشن گذاشت روی این شکلی که شما گذاشتید کار نکردم.
ولی همچنان متعقدم اگر پیامهای خطای کامل و دقیق به کاربر بدیم بهتره. و این کار نیاز به رگولار اکسپرشن های مجزا داره. البته میتونیم از یک رگولار اکسپرشن هم استفاده کنیم و قسمتهایی از اون رو که مچ شدن بعدا پیدا کنیم، ولی شاید زیادی پیچیده بشه.
در ضمن رگولار اکسپرشن شما یک اشکال داره که البته میتونید براحتی رفع کنید. اشکال از اونجا ناشی میشه که شما اسپیس و خط تیره رو داخل یک مجموعه گذاشتید و این باعث میشه مثلا از توالی یک اسپیس و یک خط تیره حتی در وسط رشته هم اشکال گرفته بشه، درحالیکه طبق قوانین ما این توالی غیرمجاز نیست.

یه چیزی میگم شاید زیاد ربطی نداشته باشه، اما شاید هم ربطی داشته باشه.
ببینید شما همینجا اومدید خواستید چنتا رگولار اکسپرشن فوق ساده رو یکی کنید، و این منجر به افزایش پیچیدگی رگولار اکسپرشن ترکیبی شما شد و در نتیجه احتمال باگ بالا رفت و دیدید که حتی شما هم که بنظرم در زمینهء رگولار اکسپرشن بقدر کافی وارد هستید، در مورد یک چیز خیلی ساده اشتباه کردید یا اینطور بگیم که از زیر دستتون در رفت و زیاد دقت نکردید.
هرچیزی هرچی پیچیده تر میشه نیاز به دقت و صرف وقت و انرژی و تست بیشتری پیدا میکنه، و با این وجود بازهم احتمال باگ بالاتر میره.
در برنامه نویسی این همیشه مسئله هست، و مطمئن باشید وقتی آدم در یک چنین موارد محدود و ساده ای و برنامهء کوچکی اشتباه یا غفلت میکنه، در برنامه های بزرگ و الگوریتم های پیچیده احتمال اشتباهات و غفلت های متعدد خیلی بیشتر میشن، هرچند سعی کنه دقت و تست بیشتری انجام بده. بالاخره انسان محدودیت هم داره و یک ابررایانهء خستگی ناپذیر نیست.

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



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

شاید شما فکر میکنید چیزایی که بنده میگم از روی غرور یا خودنمایی هست، اما اینطور نیست. حداقل 80 درصد بر اساس دانش و تجربهء روشن هست و تحلیل منطقی بسیار عمیق و گسترده. شاید بعضی جاها 20 درصد هم احساسی بشم.
حالا شما میخواید به این چیزهای ظاهرا جزیی ولی مهم و تاثیرگذار توجه نکنید و حرف خودتون رو بزنید و بنده رو به سخره بگیرید، خودتون میدونید. اما تفاوت بین یک ذهن کاملا منطقی و واقعگرا با آدم احساسی همینه.
فکر میکنم عینیت و استدلال های منطقی ای که میارم، نظرات بنده رو تایید میکنن.
هرچیزی باید یه نمود عملی داشته باشه. در اینطور موارد بقولی میگن چیزی که دیده نمیشه پس پرداختن به اون بی فایده هست؛ چون اینطور چیزا باید در عمل موثر باشن تا بگیم وجود دارن. پرفورمنس تا وقتی در عمل محدودیت جدی نباشه و دیده نشه اهمیتی نداره، و در مقابل، یوزرفرند بودن، خوانایی برنامه و امنیت و بدون باگ بودنش و انعطاف و پارامترهای دیگر اغلب کاملا مشهود و تاثیرگذار خواهند بود.
بله ما میتونیم فرضا با بهینه سازی حداکثری نرم افزارهای موجود، مقداری پرفورمنس جهانی رو افزایش بدیم. اما این کار بهای گزافی خواهد داشت اعم از میزان زیادی وقت و انرژی نفر/ساعت و افزایش باگها و کاهش امنیت و کاهش انعطاف برنامه ها و قابلیت توسعه و تغییر و نگهداری اونها... . اینا هزینه هایی به مراتب بیشتر از اون چیزی هستن که حتی 20% افزایش پرفورمنس ارزشش رو داشته باشه. بصورت مثل و قیاس و نه با تخمین دقیق اگر بخوام بگم، این عملیات و عواقب اون میلیاردها دلار هزینهء مالی خواهد داشت، که با کسری از این میلیاردها دلار میشد کمبودهای سخت افزاری رو براحتی جبران کرد.


ولی در مراحل اجرایی برنامه حتی 1 صدم ثانیه هم برای خودش خیلی مهم است و نباید از اون صرف نظر کرد.(این نظره منه!)بنده نظیر این گفته رو زیاد شنیدم، اما هیچکدام سند و استدلال قانع کننده ای برای این ادعا نیاوردن؛ بخصوص درمقابل استدلالهای بنده.
بهینه سازی به حرف آسونه و فکر میکنیم کاری نیست که هزینه ای داشته باشه، اما در عمل اغلب اینطور نیست. گذشته از این بهینه سازی اگر بخواد بخاطر 1 صدم ثانیه باشه شامل ده ها و صدها نوع بهینه سازی ممکن میشه که باید روی هرکدام از اونها فکر کرد و توی برنامه پیاده کرد؛ کار کمی نیست. بهینه سازی فقط یکی کردن چنتا رگولار اکسپرشن و استفاده از فلان تابع و فلان سینتاکس بجای تابع و سینتاکس دیگه نیست، بهینه سازیهای زیادی وجود دارن که پیچیده و علمی هستن و خودشون کلی الگوریتم و حساب و کتاب دارن.
و اگر یک صدم ثانیه واقعا اینقدر مهمه، چرا شما بجای PHP از C استفاده نمیکنید که خیلی بیشتر از یک صدم ثانیه زمان اجراتون بالا بره؟


در هرصورت من هنوز هم قانع نشدم، و اگر من باشم trim یکی از راههایی هست که بکار میبرم. به اینصورت الگوی ریگولار اکسپرشنی هم که نوشتیم بهینه تر میشه!حالا این مورد trim زیاد هم مهم نیست بنظرم و بنده روش اصراری ندارم درمورد یه چیزی مثل نام کاربری. اگر دوست دارید از trim استفاده کنید. ولی بنظر بنده در این مورد خاصی ارزشی بخاطر بهینه سازی وجود نداره. اگر ارزش قابل توجهی باشه شاید فقط بخاطر ساده تر شدن کد و الگوریتم و یوزرفرندتر شدن و این حرفا باشه.
این صدمها و هزارم های ثانیه نباید معیار اول ما در طراحی برنامه باشن. چون پارامترهای خیلی مهمتری هستن که وجود عینی و عملی دارن.

amin1softco
دوشنبه 24 مرداد 1390, 18:21 عصر
یک نکته به نظرم رسید این عبارات منظم در جاوا هم موجوده به جای اینکه یک بار بره سرور و برگرده به نظرم با آجاکس پیاده سازی بشه سریع تر می شه ها مثلاً برای چک کردن معتبر بودن ایمیل :


function IsEmail(str) {
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
if (! str.match(re)) {
return (false);
}
return(true);
}

اما خوب به نظرم سمت سرورم باید چک بشه !!!؟:متفکر:

eshpilen
دوشنبه 24 مرداد 1390, 18:29 عصر
اینکه گذاشتید ایجکس نیست، فقط جاوااسکریپت سمت کلاینته.

اما خوب به نظرم سمت سرورم باید چک بشه !!!؟
مسلما.
سمت کلاینت اصلا ارزش امنیتی نداره چون براحتی میشه دورش زد.
سمت کلاینت فقط برای راحتی و سرعت کاربر هست و کم کردن ترافیک سرور و غیره.

eshpilen
دوشنبه 24 مرداد 1390, 18:53 عصر
اینو بگم که اون برنامه ای که در این تاپیک ارائه دادم نمونهء یک کد کامل و دقیق از هیچ جهتی نیست. اگرم صحبتهایی روش میکنم بیشتر بصورت مثالی ازش استفاده میکنم و نمیخوام بگم لزوما کامله و بهترین روشها درش بکار رفته.
بطور مثال اگر یه چیزی رو ولیدیت میکنیم بنظر بنده باید ولیدیشن هایی رو که میشه با هم انجام داد در یک مرحله انجام بدیم و پیامهای خطای همهء اونها رو بصورت یکجا به کاربر نشون بدیم. مثلا اگر طول نام کاربری وارد شده کمتر از مقدار مجاز حداقل هست و در عین حال کاراکترهای غیرمجاز هم در اون هست باید هردوی این خطاها در یک مرحله چک و به کاربر گزارش بشن، نه اینکه یک بار پیام بدیم که طول نام کاربری شما کمه و کاربر طول نام کاربری رو کم کنه و بعد دوباره خطا بدیم که کاراکتر غیرمجاز توش هست. چون اینطوری ممکنه کاربر چندین بار نیاز به انتخاب و اصلاح نام کاربری پیدا کنه و سابمیت کنه (یا فرقی نمیکنه با ایجکس هم انجام بشه بهرحال فقط یخورده راحتتره) و به ستوه بیاد. البته بقول کاربر دیگر در این تاپیک، ما میتونیم تمام شرایط لازم برای نام کاربری رو هم به کاربر اطلاع بدیم.

البته احتمالا بعضی چیزها هستن که چک کردن و پیام خطا دادن همزمان اونها ممکن نیست یا مضحک و بی معنی هست. اون موارد رو باید بصورت قدم به قدم و به ترتیب اولویت و معنادار بودن چک کرد. حالا حتما میگید مثالش چیه، ولی من خودمم حضور ذهن ندارم. اما بنظرم همچین مواردی دیدم و حداقل یک احتمال ممکن هست که بخاطر کامل بودن مطلب گفتم. در مورد بعضی چیزها قاعدهء کلی مختصری وجود نداره، یا استثناء وجود داره.

eshpilen
دوشنبه 24 مرداد 1390, 19:48 عصر
اگر برنامه پیامهای خطای کامل و دقیق بده، برنامه نویس خودش موقع تست و توسعه سریعتر و موفق تر خواهد بود. حتی به این شکل باگهایی کشف میشن که در غیراینصورت براحتی ممکنه برنامه نویس متوجه وجود اونها نشه.
در این مورد یخورده بیشتر توضیح بدم بهتره :لبخند:
هرچی میگن زیاد ننویس ولی بنده شخصا دوست دارم مطلب کامل و دقیق باشه و بنابراین هرچی بنظرم لازم باشه و به فکرم برسه مینویسم.

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

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

تازه این برنامه هم که بنده در این تاپیک درج کردم از این نظر نقص داره، چون درواقع همونطور که گفتم باید حتی الامکان تمام چک ها در یک مرحله سابمیت شدن انجام بشن و پیامهای خطا همه با هم تولید و نمایش داده بشن. اینطوری آدم میفهمه که مثلا برنامه از ورودی مورد نظر یک اشکال نگرفته، بلکه دوتا یا بیشتر اشکال گرفته. این هم برای برنامه نویس خوبه و هم برای کاربر.
البته گفتم که این امر استثناء هم داره و مثلا درمورد چک ها و پیامهای خطایی که گفتم غیرمنطقی هست با هم انجام بشن یک مورد چک کردن خالی بودن ورودی هست. مثلا اگر کاربر چیزی وارد نکرده ما فقط باید بخش چک کردن خالی نبودن فیلد رو انجام بدیم و پیام خطا تولید کنیم، نه اینکه رگولار اکسپرشن ها هم اجرا بشن که ممکنه پیامهای خطای بی معنی تولید کنن. مثلا وقتی کاربر اصلا چیزی وارد نکرده برنامه پیام میده که کاراکتر غیرمجاز وارد شده!!

eAmin
دوشنبه 24 مرداد 1390, 23:18 عصر
ببینید پارامترها از هم جدا هستن و هرکدام ارزشی دارن. مثلا افزایش پرفورمنس های جزیی امروزه در بیشتر موارد اپلیکیشن نویسی اهمیت و اولویتی ندارن، چون در عمل برای کاربر تاثیری ندارن یا تاثیر ناچیزی دارن.
اما قضیهء فانکشنالیتی، امنیت، یوزرفرند بودن و اینا مهم هستن، چون در عمل تاثیر زیادی دارن.
شما میتونید کاربر رو سردرگم بذارید، اما این کار رو نکنید و دقیقا علت خطای رخ داده رو بیان کنید خیلی بهتره.

نظر شما درباره اینکه وقتی کاربر به هنگام لاگین کردن اگر یکی از فیلدهای نام کاربری یا پسورد رو اشتباه وارد کنه چیه؟ اینکه ما دقیقا به کاربر بگیم کدام یک از موارد رو اشتباه وارد کرده یا نه بگیم یکی از موارد زیر رو اشتباه وارد کردید؟
شاید خیلی ربط نداشته باشه ولی برای اینکه منظورم رو بهتر برسونم مفیده.
ببینید گاهی اوقات لازمه از موارد ریز و جزئی پرهیز کنیم، و در موردی که عرض کردم الزاما برای امنیت نسبی که بهمراه خودش داره. اینکه کدهای برنامه به اجزای جدا و کوچکتر تبدیل بشن از لحاظ خوانایی و Debug خیلی بهتر و خوانا تر هستن شکی نیست و کسی ه منکر این قضیه نیست. ولی روشهای خیلی بهتری وجود داره که علتش برای شما چند خط پایین تر توضیح میدم.



ضمنا همونطور که گفتم این کار به نفع خود برنامه نویس هم هست و کار چندان سختی نیست. اگر برنامه پیامهای خطای کامل و دقیق بده، برنامه نویس خودش موقع تست و توسعه سریعتر و موفق تر خواهد بود. حتی به این شکل باگهایی کشف میشن که در غیراینصورت براحتی ممکنه برنامه نویس متوجه وجود اونها نشه.
.
.
یه چیزی میگم شاید زیاد ربطی نداشته باشه، اما شاید هم ربطی داشته باشه.
ببینید شما همینجا اومدید خواستید چنتا رگولار اکسپرشن فوق ساده رو یکی کنید، و این منجر به افزایش پیچیدگی رگولار اکسپرشن ترکیبی شما شد و در نتیجه احتمال باگ بالا رفت و دیدید که حتی شما هم که بنظرم در زمینهء رگولار اکسپرشن بقدر کافی وارد هستید، در مورد یک چیز خیلی ساده اشتباه کردید یا اینطور بگیم که از زیر دستتون در رفت و زیاد دقت نکردید.
هرچیزی هرچی پیچیده تر میشه نیاز به دقت و صرف وقت و انرژی و تست بیشتری پیدا میکنه، و با این وجود بازهم احتمال باگ بالاتر میره.
در برنامه نویسی این همیشه مسئله هست، و مطمئن باشید وقتی آدم در یک چنین موارد محدود و ساده ای و برنامهء کوچکی اشتباه یا غفلت میکنه، در برنامه های بزرگ و الگوریتم های پیچیده احتمال اشتباهات و غفلت های متعدد خیلی بیشتر میشن، هرچند سعی کنه دقت و تست بیشتری انجام بده. بالاخره انسان محدودیت هم داره و یک ابررایانهء خستگی ناپذیر نیست.

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

اتفاقا یکی از همین جاها است که استفاده از روش ها و یا پروسه های طراحی/توسعه نرم افزار مثل TDD ـ (Test-driven development) (http://en.wikipedia.org/wiki/Test-driven_development)در طول پیاده سازی برنامه خودش رو آشکار میکنه و خیلی مهم است. این روش برای این بوجود اومده تا دقیقا از راههایی که شما بهش اشاره کردید مثل تکیه تیکه کردن رگولار اکسپرشن و موارد این چنینی و جزئی کمی صرف نظر کنیم. چون در مرحله تست در این روش شما می تونید تمامی روشهای موجود و ناشناخته رو تست کنید و اگر مشکلی در روند اجرای تابع یا برنامه پیش آمد سریعا اون رو مرتفع کنید.
اگر کمی دقت کنید می بینید که در الگوی RegExp بنده هم اجزا به بخشهای مختلفی تقسیم شدن، اتفاقا به همین دلیل که در RegExp چنین قابلیتی وجود داره بنده اینکار رو کردم و از این رو بنظرم برای کسی که بتونه و قادر به درک کردن الگوهای رگولار اکسپرشن باشه، کد خوانا تری هست و کد نویسی کثیف اجتناب کردیم!
مثلا بزارید یک مثالی در JavaScript برای شما بزنم (در php زیاد مطمئن نیستم و تا حالا امتحان نکردم بخاطر همین از php فاکتور گرفتم)، در CSS Selector Engine های معروف که در framework ها بکار برده شده سعی بر این داشتند که حداکثر تمامی الگوها رو در یک الگو پیاه سازی کنند، البته به قسمتهای مختلف. مثلا می تونستند که برای جستجو بر اساس id,class,tag, attribute و... از یک الگوی جداگانه استفاده کنند ولی چون این قابلیت در Regular Expression هست که الگو رو به بخشهای مختلف تقسیم کنید از این قابلیت استفاده کردند.


بنده نظیر این گفته رو زیاد شنیدم، اما هیچکدام سند و استدلال قانع کننده ای برای این ادعا نیاوردن؛ بخصوص درمقابل استدلالهای بنده.
بهینه سازی به حرف آسونه و فکر میکنیم کاری نیست که هزینه ای داشته باشه، اما در عمل اغلب اینطور نیست. گذشته از این بهینه سازی اگر بخواد بخاطر 1 صدم ثانیه باشه شامل ده ها و صدها نوع بهینه سازی ممکن میشه که باید روی هرکدام از اونها فکر کرد و توی برنامه پیاده کرد؛ کار کمی نیست. بهینه سازی فقط یکی کردن چنتا رگولار اکسپرشن و استفاده از فلان تابع و فلان سینتاکس بجای تابع و سینتاکس دیگه نیست، بهینه سازیهای زیادی وجود دارن که پیچیده و علمی هستن و خودشون کلی الگوریتم و حساب و کتاب دارن.
و اگر یک صدم ثانیه واقعا اینقدر مهمه، چرا شما بجای PHP از C استفاده نمیکنید که خیلی بیشتر از یک صدم ثانیه زمان اجراتون بالا بره؟

بزارید اینطور بگم تا زمانی که بتونیم و از دستمون بر بیاد سعی کنیم از روشهای بهینه سازی هم استفاده کنیم. در ضمن منظور بنده در محیط و زبان برنامه نویسی ای که داریم از اون استفاده می کنیم بوده و هست.
درضمن مطمئن باشید اگر یک روزی به این حد از بهینه سازی نیاز پیدا کردم، در استفاده کردن از زبان C درنگ نمی کنم!

eshpilen
سه شنبه 25 مرداد 1390, 00:04 صبح
نظر شما درباره اینکه وقتی کاربر به هنگام لاگین کردن اگر یکی از فیلدهای نام کاربری یا پسورد رو اشتباه وارد کنه چیه؟ اینکه ما دقیقا به کاربر بگیم کدام یک از موارد رو اشتباه وارد کرده یا نه بگیم یکی از موارد زیر رو اشتباه وارد کردید؟

در اینجا از نظر امنیتی نباید بگیم کدوم یکی از نام کاربری یا پسورد اشتباهه. چون اینطوری میتونن نامهای کاربری موجود رو چک کنن.
ولیدیشن و پیام خطای با جزییات که همه جا بکار نمیره. بیشتر موقع ثبت نام و درج اطلاعاتی در دیتابیس استفاده میشه.
هرچند فکر کنید طرف با استفاده از همون بخش ثبت نام هم میتونه چک کنه نام کاربری موجود هست یا نه :متفکر:
دهه من که خودم شک کردم :لبخند:
البته بهرحال بهتره این دو بخش رو بهم ربط ندیم. شاید یه وقت یه سایتی اصلا بخش ثبت نام عمومی نداشت به اون شکل، ولی بخش لاگین عمومی که داره!


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



اتفاقا یکی از همین جاها است که استفاده از روش ها و یا پروسه های طراحی/توسعه نرم افزار مثل TDD ـ (Test-driven development) (http://en.wikipedia.org/wiki/Test-driven_development)در طول پیاده سازی برنامه خودش رو آشکار میکنه و خیلی مهم است. این روش برای این بوجود اومده تا دقیقا از راههایی که شما بهش اشاره کردید مثل تکیه تیکه کردن رگولار اکسپرشن و موارد این چنینی و جزئی کمی صرف نظر کنیم. چون در مرحله تست در این روش شما می تونید تمامی روشهای موجود و ناشناخته رو تست کنید و اگر مشکلی در روند اجرای تابع یا برنامه پیش آمد سریعا اون رو مرتفع کنید.والا من تاحالا از روش و ابزار خاصی برای تست و دیباگ استفاده نکردم. بنابراین نمیتونم نظری بدم.
ولی روشهایی که خودم بکار میبرم بنظرم نسبتا خوب کار میکنن و از طرف دیگه باعث شدن در تست و باگیابی قوی و مستقل باشم. حتی باگهای پیچیده رو هم خیلی وقتا نسبتا به سرعت پیدا و حل میکنم.
در ضمن فکر نمیکنم هیچ ابزاری بتونه در تمام موارد جایگزین انسان بشه و همه کار رو بصورت خودکار و بدون نقص انجام بده.


اگر کمی دقت کنید می بینید که در الگوی RegExp بنده هم اجزا به بخشهای مختلفی تقسیم شدن، اتفاقا به همین دلیل که در RegExp چنین قابلیتی وجود داره بنده اینکار رو کردم و از این رو بنظرم برای کسی که بتونه و قادر به درک کردن الگوهای رگولار اکسپرشن باشه، کد خوانا تری هست و کد نویسی کثیف اجتناب کردیم!آره اونم بد نیست. ولی مال منم بد نیست. هیچکدام اونقدری بد نیستن. و مطمئن نیستم کدام بهتره. حرف من همینه که این مسائل خیلی اهمیت ندارن و نمیشه فتوای مطلق داد. بخصوص چون بیشتر استدلال روی پرفورمنس میشه، درحالیکه اول باید اونطور که خواناست و از نظر تست و توسعه و انعطاف و اینطور چیزا بهتره هرچیزی رو انجام داد. واسه من اون موقع نوشتن اونا خیلی راحتتر بود و باعث میشد مراحل الگوریتم رو بخوبی ببینم و در ذهنم تحلیل کنم. لزومی هم به تغییرش در مراحل بعدی نمیبینم. یعنی دلیل واضح و مهمی بنظرم نمیرسه. البته کوتاهی روش شما نظرم رو جلب کرد چون از پیچیدگی شرطهای تودرتو کم میکنه. بهرحال من بازم روش خودم رو ترجیح میدم چون پیام خطای دقیق دادن درش راحتتره و این برای تست و حتی کشف باگهای کمیاب موقع کارکرد عادی برنامه خیلی مهمه.


مثلا بزارید یک مثالی در JavaScript برای شما بزنم (در php زیاد مطمئن نیستم و تا حالا امتحان نکردم بخاطر همین از php فاکتور گرفتم)، در CSS Selector Engine های معروف که در framework ها بکار برده شده سعی بر این داشتند که حداکثر تمامی الگوها رو در یک الگو پیاه سازی کنند، البته به قسمتهای مختلف. مثلا می تونستند که برای جستجو بر اساس id,class,tag, attribute و... از یک الگوی جداگانه استفاده کنند ولی چون این قابلیت در Regular Expression هست که الگو رو به بخشهای مختلف تقسیم کنید از این قابلیت استفاده کردند.والا من فکر میکنم مقایسهء اینطور نرم افزارها با اپلیکیشن نویسی وب با PHP چندان قیاس منطقی روشنی نباشه. باید بیشتر روش فکر کرد.
اونا یه نرم افزارهای سطح پایین تر و پایه تر هستن که یجورایی سرویس میدن و نیاز هست پرفورمنس بالاتری داشته باشن و ضمنا برنامه نویسان حرفه ای با سالها تجربه روی اونها وقت و انرژی زیادی میذارن و کلی تست میشه و خلاصه تشکیلات عریض و طویلی داره که برای امثال ما برنامه نویسان عادی و منفرد و این کارهای سطح بالا و عادی توجیه و حتی امکانش نیست.
ما هم اگر روی یک نرم افزار خاص یا مثلا ماجول ها و کتابخانه های عمومی ای که طراحی میکنیم و در برنامه های مختلف از اونا استفادهء مجدد میکنیم زیاد کار کنیم مهارت و تسلط پیدا میکنیم و خیلی راحتتر میتونیم روی اونا وقتی که به تدریج به بلوغ و کمال کلی از جهات دیگه رسیدن بهینه سازی کنیم و این بهینه سازیها خیلی با معناتر از کدهای یک بار مصرف و پراکنده در برنامه های مختلف هستن، چون به بخشهای مختلفی سرویس میدن و در برنامه های زیادی Reuse میشن.


درضمن مطمئن باشید اگر یک روزی به این حد از بهینه سازی نیاز پیدا کردم، در استفاده کردن از زبان C درنگ نمی کنم!
خوبه دیگه خودتون گفتید: وقتی نیاز پیدا کردید!
پس الان نیازی ندارید برنامه های وب شما با سرعت چند برابر اجرا بشن.
البته اگر به همین راحتی میشد که کسی بدش نمیاد، ولی موضوع هزینه های دیگری هست که برنامه نویسی با سی داره.
اصلا زبانهای سطح بالا و فریمورک ها بخاطر همین بوجود میان چون راحتی و سرعت برنامه نویسی خیلی اهمیت داره. وگرنه تمام این زبانها و فریمورک ها خودشون خورهء منابع و پرفورمنس هستن در مقایسه با زبانهای سطح پایین. بنابراین بنظر من آدم نباید در یه زبان سطح بالا مدام تفکر سطح پایین داشته باشه و طوری خودش رو محدود کنه و عذاب بده که از بخشی از مزایای زبانهای سطح بالا محروم بشه. زبان سطح بالا برای اینه که شما روی الگوریتم و امکانات اصلی متمرکز بشی و با جزییات فنی و داخلی کامپیوتر و اجرا حداقل سروکار رو داشته باشی و اون کارها بصورت خودکار انجام بشن و بقدر کافی بهینه باشن. خب هیچ سیستمی کامل و همه کاره و همه جایی نیست، و بنابراین یه جایی ممکنه عملا اون سیستم جواب نده و مثلا مشکل پرفورمنس داشته باشی، اونوقت میبینی چون دیده میشه، و میری درستش میکنی، چون دیگه سیستم اون کار رو بدرستی برات انجام نمیده.

eAmin
سه شنبه 25 مرداد 1390, 00:28 صبح
والا من تاحالا از روش و ابزار خاصی برای تست و دیباگ استفاده نکردم. بنابراین نمیتونم نظری بدم.
ولی روشهایی که خودم بکار میبرم بنظرم نسبتا خوب کار میکنن و از طرف دیگه باعث شدن در تست و باگیابی قوی و مستقل باشم. حتی باگهای پیچیده رو هم خیلی وقتا نسبتا به سرعت پیدا و حل میکنم.
در ضمن فکر نمیکنم هیچ ابزاری بتونه در تمام موارد جایگزین انسان بشه و همه کار رو بصورت خودکار و بدون نقص انجام بده.

بیشتر این پروسه رو با نام Unit Testing می شناسند. یکی از بهترین روشهای عیب یابی در مراحل توسعه نرم افزار هست و سرعت بسیار بالاتری نسبت به انسان هم داره:چشمک:
راستش این ابزاری هست که خودمون می نویسیم و تمامی تستها رو خودمون اضافه می کنیم، اگر درست اجرا شد پیغام مناسبی چاپ میش و اگر در فرآیند اجرا مشکلی پیش بیاد با خطا یا warning بعد از تست کردن به ما گزارش داده میشه، تقریبا مثل یک فایل log میمونه با این تفاوت که تست هایی رو که ما بهش گفتیم رو اجرا و نتیجه رو اعلام میکنه.
البته فریم ورکهای مخصوص به اینکار هم نوشته شده که از اونها هم می تونید استفاده کنید.

eshpilen
سه شنبه 25 مرداد 1390, 00:35 صبح
ضمنا منظوری ندارم جسارت نشه کلی عرض میکنم، این بهینه سازیهای جزیی اکثرا هنری نیستن و میبینی خیلی از افرادی که کارهای مهمتر که طراحی الگوریتم های درست و کامل برای حل مسائل اصلی و امنیت هست رو نمیتونن یا به هر علتی که نمیدونم درست و کامل انجام نمیدن هستن که مدام به چیزهای پیش پا افتاده مثل بهینه سازی اینکه از کدوم تابع و سینتاکس استفاده کنیم گیر میدن. من نمیدونم اینقدر وقت و انرژی تلف کردن روی این مسائل واقعا چه ارزشی داره! اینقدر دانش و مهارت مهمتر و ضروری هست که آدم نباید اینقدر وقت خودش رو فقط روی این چیزهای کم کاربرد و کم اهمیت صرف کنه.

در همین برنامه نگاه کنید مهمترین چیزش طراحی رگولار اکسپرشن اولش بوده (صرفنظر از اینکه شکلش از نظر کد و بهینه سازی چی هست) و اینکه درست تصمیم بگیریم که محدودیت های ما چی باشن - یعنی دانش و بینش امنیتی صحیح. این بهینه سازی های جزیی از نظر اهمیت هیچی نیست درمقابل اینا. ضمنا هروقت نیاز بشه آدم میتونه حلش کنه. کاری نداره که!
اینهمه آدم که مدام از بهینه سازی حرف میزنن اینهمه مدت یه رگولار اکسپرشن درست و حسابی برای این کار و تشخیص و تفکیک کاراکترهای فارسی درست نکرده بودن. اینو دیگران در این تاپیک بصورت ضمنی یا صریح گفتن. غیر از اینه؟
ضمنا این که چیزی نبود. درواقع خیلی ساده بود! تازه یه مورد کلی تر از رگولار اکسپرشن فارسی موجود بود که بنده همون رو الگو قرار دادم و منم کار زیادی نکردم چون همه چیز رو از صفر خودم انجام ندادم. ولی هیچکس دیگه این کار ساده رو نکرده بود.
بحث تعریف از خودم نیست. بحث این هست که ما مسائل مهمتر و عملی تر رو رها کردیم و مدام به چیزهای پیش پا افتاده و دارای اهمیت عملی کم گیر میدیم.

منکه مدام برنامه نویسی نمیکنم و سایت و اپلیکیشن تحویل مردم نمیدم. یه شغل ثابت غیر از برنامه نویسی دارم فعلا. در عمرم هم چنتا پروژهء کوچک تمرینی انجام دادم و یکی دو کار محدود که میشه بهشون تجاری گفت. بعد تعجب میکنم چطور اینهمه برنامه نویس که کارهای تجاری میکنن این مسائل ساده و پایه رو هنوز حل نکردن. هنوز یه رگولار اکسپرشن بدرد بخور برای ولیدیشن فارسی برای نام کاربری موجود نبود که همه بشناسن و ازش استفاده کنن.

هرکس از راه میرسه دربارهء این چیزا میپرسه و ده تا راه حل و نظر میدن که 8 تاش اشتباهه و اونایی هم که درسته اکثرا ناقص و ناشیانه هست.
یکی میرسه یه بلک لیست میده که اصلا معلوم نیست یعنی چی و کجا چرا استفاده داره و هیچکس هم هیچی نمیگه. نهایتش میگن پیچیده هست و نمیشه فهمید! حتی از بحث و تحلیل هم عاجز هستیم یا فکر میکنیم ازش چیزی عاید نمیشه؟
حالا دلمون رو به بهینه سازی از نوع تابع و سینتاکس و یکی کردن چند دستور و فراخوانی خوش کنیم. اینقدر که دقیق و وسواسی و حرفه ای و کمال گرا هستیم پس چرا مسائل دیگر رو حل نکردیم؟
تمام اینا مسائل پایه و صد درجه مهمتر از بهینه سازی هست در حوزهء کاری ما.

eshpilen
سه شنبه 25 مرداد 1390, 00:43 صبح
بیشتر این پروسه رو با نام Unit Testing می شناسند. یکی از بهترین روشهای عیب یابی در مراحل توسعه نرم افزار هست و سرعت بسیار بالاتری نسبت به انسان هم داره:چشمک:
راستش این ابزاری هست که خودمون می نویسیم و تمامی تستها رو خودمون اضافه می کنیم، اگر درست اجرا شد پیغام مناسبی چاپ میش و اگر در فرآیند اجرا مشکلی پیش بیاد با خطا یا warning بعد از تست کردن به ما گزارش داده میشه، تقریبا مثل یک فایل log میمونه با این تفاوت که تست هایی رو که ما بهش گفتیم رو اجرا و نتیجه رو اعلام میکنه.
البته فریم ورکهای مخصوص به اینکار هم نوشته شده که از اونها هم می تونید استفاده کنید.
الان که بیشتر توضیح دادید متوجه شدم (البته حدس میزدم). قبلا در اینمورد خوندم. فقط عملی چیزی ندیدم.
بنده هنوز وقت نکردم روی این چیزا کار کنم. شاید چون پروژهء تجاری و عملی جدی و بزرگی نداشتم و احساس نیاز نمیکردم.
اینقدر مسائل برای یادگیری زیاد بود و بنظر بنده چیزهای دیگر و مباحث پایه مثل الگوریتم و دانش امنیت مهمتر بودن که دنبال اینطور چیزا نرفتم. هرچند این روش هم ابزاری برای برقراری امنیت و پایداری برنامه هست.

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

alismith
سه شنبه 25 مرداد 1390, 12:22 عصر
هرکس از راه میرسه دربارهء این چیزا میپرسه و ده تا راه حل و نظر میدن که 8 تاش اشتباهه و اونایی هم که درسته اکثرا ناقص و ناشیانه هست.
یکی میرسه یه بلک لیست میده که اصلا معلوم نیست یعنی چی و کجا چرا استفاده داره و هیچکس هم هیچی نمیگه. نهایتش میگن پیچیده هست و نمیشه فهمید! حتی از بحث و تحلیل هم عاجز هستیم یا فکر میکنیم ازش چیزی عاید نمیشه؟

سلام

دوست عزیز من به دانش شما شک ندارم
و به زبان php هم خیلی علاقه دارم ، به شخصه خیلی ها رو دیدم که با همین زبان برنامه نویسی می کنند که اصلا رشته تحصیلی شون کامپیوتر نبوده و برنامه نویس حرفه ای هم نیست
ولی به دلیلی میشه گفت مثلا ساده بودن این زبان و قابل درک بودنش ، علاقه مند شدن و الان دارن کار می کنن، حتی شاید در انجام پروژه های بزرگی هم سهیم باشن، با این حال نمیشه گفت هر شخصی که برنامه نویسی بلد هستش چه رشته کامپیوتر چه هر رشته ای ، برنامه نویسی رو از پایه شروع کرده و اصولی رفته جلو
مثلا همین طور که شما هم گفتید


بحث این هست که ما مسائل مهمتر و عملی تر رو رها کردیم و مدام به چیزهای پیش پا افتاده و دارای اهمیت عملی کم گیر میدیم

اینهمه برنامه نویس که کارهای تجاری میکنن این مسائل ساده و پایه رو هنوز حل نکردن.

مسئله اینه که (من به شخصه خودم رو مثال میزنم) انتخاب راه درست رو بلد نیستیم
نمیدونیم یک پروژه رو چطور از اول تحلیل کنیم بعد اون نیاز ها رو با کد نویسی رفع کنیم (همون بلوغی که گفتید)
بعد بهینه سازی کنیم
بعضی وقت ها هم چون مثلا دانش یک کاری رو ندایم با حذف اون امکان از پروژه میخایم به پیشرفت کار کمک کنیم
ولی کلا همون طور که گفتید خودمون هم میدونیم داریم به چیزهای پیش پا افتاده و دارای اهمیت عملی کم گیر میدیم، اما خوب شاید فکر می کنیم ، داریم کار پروژه رو پیش میبریم
البته همه اینجوری نیستن ، خیلی ها هستن که مسمم هستن در کارشون و با تخصصی که دارن به هدفشون هم میرسن، حالا چه در یک شرکت معتبر اروپایی ، چه به تنهایی و در ایران برنامه نویسی کنه
فرقی نداره
مهم امادگی فرد هستش برای تحلیل مسائل
که تمام این ها مربوط میشه به دانش فرد در برنامه نویسی و مهمترین عامل یعنی تجربه

با این حال شما و برخی دوستان در این انجمن تلاش زیادی برای پیاده سازی استانداردها انجام میدید
که واقعا قابل تحصین هستش

امیدوارم باز هم ما رو با مقالات و بحث های جالبتون بهره مند سازید

موفق باشید