سلام.
همونطور که حتما توی صفحه لاگین اینستاگرام دیدین محدودیتی برای ورود ایمیل یا نام کاربری وجود نداره. یعنی به همراه پسورد چه ایمیل رو بزنید و چه نام کاربری رو میتونید لاگین بشید.
این قابلیت با یک تغییر خیلی جزئی در تابعی که اطلاعات یوزر رو برای لاگین چک میکنه قابل انجامه:
function checkUser($info){
global $pdo;
$username = $info['username'];
if (validEmail($username)){
$sql2 = "where email = ?";
}else{
$sql2 = "where username = ?";
}
$sql = "select * from users " . $sql2;
$stmt = $pdo->prepare($sql);
$stmt->bindValue(1,$username);
$stmt->execute();
$res = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $res[0];
}
همونطور که مشاهده می کنید، با استفاده از تابع validEmail میتونیم بفهمیم که مقداری که کاربر در فیلد مربوط به usernamr/email وارد کرده نام کاربریش هست یا ایمیلش و بنا بر مقدار وارده کوئری رو تغییر میدیم.
پیاده سازی تابع validEmail هم بصورت زیر هست:
function validEmail($email){
if(filter_var($email, FILTER_VALIDATE_EMAIL)){
return true;
}else{
return false;
}
}
به همین راحتی!
این خط در واقع تعیین میکنه متغیری که میخوایم توی کوئری به دیتابیس مون قرار بدیم چیه.
کوئری اینه
$sql = select * from users where username = ?;
اون خطی که نوشتی میگه جای علامت سوال متغیر $username رو قرار بده.
در واقع به تعدادی که توی کوئری مون علامت سوال بذاریم باید تابع bindValue رو صدا بزنیم.
مثلا :
$sql = select * from users where username = ? And password = ?;
$stmt = $pdo->prepare($sql);
$stmt->bindValue(1,$username);
$stmt->bindValue(2,$password);
حالا چرا اینکار رو میکنیم و متغیر رو مستقیم توی استرینگ نمیذاریم؟
Prepare و چون تابع bindValue خودشون یسری بررسی های امنیتی رو لحاظ میکنه روی متغیرمون. مثلا بررسی میکنه جای متغیر کاربر کد sql وارد نکرده باشه.
برای اطلاعات بیشتر توی این حوزه بهتره درباره حملات Sql injection مطالعه کنی...