دسته بندی
دسترسی سریع
نحوه ذخیره کردن اطلاعات با دستور INSERT در MySQL
ارتباط با پایگاه داده MySQL
ساخت جدول و ستون ها
شیوه نگارش (Syntax) دستور INSERT
ذخیره مقادیر با دستور INSERT INTO در دیتابیس
ایمن سازی مقادیر ورودی به دیتابیس در اکستنشن MySQLi
ایمن سازی پارامترها با تابع mysqli_real_escape_string
ایمن سازی پارامترها با Prepared Statement و Bind Param
ارتباط با پایگاه داده MySQL
ساخت جدول و ستون ها
شیوه نگارش (Syntax) دستور INSERT
ذخیره مقادیر با دستور INSERT INTO در دیتابیس
ایمن سازی مقادیر ورودی به دیتابیس در اکستنشن MySQLi
ایمن سازی پارامترها با تابع mysqli_real_escape_string
ایمن سازی پارامترها با Prepared Statement و Bind Param
نحوه ذخیره کردن اطلاعات با دستور INSERT در MySQL

پس از آشنایی با نحوه ساخت دیتابیس، جدول و ستون با دستور CREATE در پایگاه داده MySQL و به کمک اکستنشن MySQLi، اکنون نوبت فراگیری قابلیت متداول دیگری از این سیستم مدیریت پایگاه داده است، هدف از این آموزش آشنایی با نحوه درج اطلاعات از طریق کدهای PHP با دستور INSERT INTO در جداول و ستون های MySQL است، قاعدتا صرف ساخت پایگاه داده، جدول و ستون کاربرد عملی نخواهد داشت و همه ی این مقدمات برای فراهم کردن شرایطی است که بتوانیم اطلاعاتمان را پیش از هر کار دیگری ذخیره سازی و در مواقع لزوم از آنها استفاده نمائیم، در واقع می توان گفت ذخیره سازی اطلاعات اولین مرحله تعامل با داده ها در دیتابیس است.
ارتباط با پایگاه داده MySQL
در آموزش های قبل گفتیم که قبل از انجام هر کاری ابتدا باید به پایگاه داده MySQL متصل شویم، طبق روال آموزش ها برای این کار از اکستنشن MySQLi و کدی مشابه به مثال زیر استفاده می کنیم.
برنامه نویسی رویه ای (Procedural):
<?php
//اتصال به دیتابیس
$conn = mysqli_connect("localhost", "username", "password", "dbname");
if(!$conn) {
echo "PHP & MySQL Connection: Error! " . mysqli_connect_errno() . ' - ' . mysqli_connect_error();
exit;
} else {
echo "PHP & MySQL Connection: Ok!<br>";
}
//پایان اتصال
mysqli_close($conn);
?>
برنامه نویسی شی گرا (Object-oriented):<?php
//اتصال به دیتابیس
$conn = new mysqli("localhost", "username", "password", "dbname");
if(!$conn) {
echo "PHP & MySQL Connection: Error! " . $conn->errno . ' - ' . $conn->error;
exit;
} else {
echo "PHP & MySQL Connection: Ok!<br>";
}
//پایان اتصال
$conn->close();
?>
در این نمونه کد فرض بر این است که از قبل دیتابیسی با نام dbname را ساخته ایم (برای آشنایی با نحوه ساخت دیتابیس لطفا به آموزش قبل مراجعه کنید)، برای تکمیل کد نیز پرس و جوی ایجاد جدول فرضی books و ستون های id، book و level را در ادامه اجرا می کنیم.ساخت جدول و ستون ها
قبل از INSERT اطلاعات، در پایگاه داده dbname جدولی فرضی با نام books می سازیم تا لیست چند کتاب و سطح آنها را جهت تست و به عنوان نمونه در ستون های book و level ذخیره کنیم، برای این منظور ابتدا با دستور CREATE جدول و ستون ها را ایجاد می کنیم (گفتیم که علاوه بر دستورات PHP، ایجاد دیتابیس، جدول و ستون از طریق رابط کاربری برنامه phpMyAdmin نیز امکانپذیر است).
برنامه نویسی رویه ای (Procedural):
<?php
//اتصال به دیتابیس
$conn = mysqli_connect("localhost", "username", "password", "dbname");
if(!$conn){
echo "PHP & MySQL Connection: Error! " . mysqli_connect_errno() . ' - ' . mysqli_connect_error();
exit;
} else {
echo "PHP & MySQL Connection: Ok!<br>";
//ساخت جدول و ستون ها
$sql = "CREATE TABLE books(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
book VARCHAR(255),
level VARCHAR(255))
ENGINE=MyISAM DEFAULT CHARACTER SET=utf8 COLLATE=utf8_persian_ci";
$query = mysqli_query($conn, $sql);
if(!$query) {
echo "Creating Table books: Error! " . mysqli_error($conn);
} else {
echo "Creating Table books: OK!";
}
}
//پایان اتصال
mysqli_close($conn);
?>
برنامه نویسی شی گرا (Object-oriented):<?php
//اتصال به دیتابیس
$conn = new mysqli("localhost", "username", "password", "dbname");
if(!$conn) {
echo "PHP & MySQL Connection: Error! " . $conn->errno . ' - ' . $conn->error;
exit;
} else {
echo "PHP & MySQL Connection: Ok!<br>";
//ساخت جدول و ستون ها
$sql = "CREATE TABLE books(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
book VARCHAR(255),
level VARCHAR(255))
ENGINE=MyISAM DEFAULT CHARACTER SET=utf8 COLLATE=utf8_persian_ci";
$conn->query($sql);
if(!$conn) {
echo "Creating Table books: Error! " . $conn->error;
} else {
echo "Creating Table books: OK!";
}
}
//پایان اتصال
$conn->close();
?>
توضیح:- اطلاعات اتصال را با توجه به نام کاربری، کلمه عبور و عنوان پایگاه داده خود در تابع mysqli_connect (برنامه نویسی رویه ای) یا کلاس mysqli (برنامه نویسی شی گرا) تعریف می کنیم (نام کاربری در localhost معمولا root و بدون کلمه عبور است).
- در مثال بالا جدولی فرضی با نام books ساخته و سه ستون در آن ایجاد کرده ایم (id, book, level)، ستون id به صورت INT عددی و افزایش خودکار (AUTO_INCREMENT) و ستون های book و level از نوع VARCHAR متنی هستند که برای ذخیره سازی متن های کوتاه (در اینجا تا 255 بایت) کاربرد دارند.
- INT و VARCHAR نوع داده (Data Types) ای هستند که در ردیف ها قابل ذخیره سازی است، این امکان در MySQL وجود دارد که از مقادیر INT برای اعداد، VARCHAR برای متن های کوتاه با مقادیر مشخص یا نوع داده TEXT، MEDIUMTEXT، LONGTEXT برای متن های طولانی استفاده کنیم (در این خصوص در آموزش های آینده مفصلا صحبت خواهیم کرد).
- مقادیر NOT NULL و AUTO_INCREMENT جزء ویژگی هایی هستند که هر نوع از داده ای مقادیر بخصوص خود را می تواند داشته باشد، به طور مثال برای INT که یک مقدار عددی است خاصیت AUTO_INCREMENT به معنی افزایش خودکار کاربرد دارد و افزایش خودکار یعنی با هر بار INSERT اطلاعات در جدول، یک مقدار به ستون مورد نظر (معمولا id) به صورت خودکار اضافه خواهد شد (شمارش پیش فرض از 1، 2، 3 و...) و نیازی به درج این مقدار به صورت دستی نیست، همچنین NOT NULL یعنی مقدار پیش فرض ستون ها NULL نیست و در صورتی که هنگام INSERT اطلاعات برای آن ستون مقداری در نظر نگیریم، مقدار خالی (به جای عبارت NULL) درج خواهد شد.
شیوه نگارش (Syntax) دستور INSERT
برای اجرای دستور INSERT می توانیم از دو شیوه نگارش استفاده و نام جدول و ستون ها را با دو Syntax زیر بنویسیم:
INSERT INTO tbl(col_1, col_2) VALUES('value_1', 'value_2')
INSERT INTO `tbl`(`col_1`, `col_2`) VALUES('value_1', 'value_2')
تفاوت روش دوم (استفاده از علامت ` backquote یا backtick) با حالت عادی در این است که با این کار در صورتی که از فضای خالی یا عبارات محفوظ MySQL به عنوان نام جدول یا ستون ها استفاده کنیم برنامه با خطای ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near...
یا خطاهای مشابه مواجه نمی شود، در هر صورت بهتر است از فضای خالی یا عبارات محفوظ برای نام جدول و ستون ها استفاده نشود:https://dev.mysql.com/doc/refman/5.5/en/keywords.html
در آدرس بالا لیست این عبارات به تفکیک حروف الفبای انگلیسی درج شده است.ذخیره مقادیر با دستور INSERT INTO در دیتابیس
پس از ساختن جدول و ستون، اکنون می خواهیم جهت نمونه نام سه کتاب فرضی آموزش HTML، آموزش PHP و آموزش MySQL را به لیست خود اضافه کنیم، بدین منظور از کدی مشابه مثال زیر استفاده می کنیم.
برنامه نویسی رویه ای (Procedural):
<?php
//اتصال به دیتابیس
$conn = mysqli_connect("localhost", "username", "password", "dbname");
if(!$conn){
echo "PHP & MySQL Connection: Error! " . mysqli_connect_errno() . ' - ' . mysqli_connect_error();
exit;
} else {
echo "PHP & MySQL Connection: Ok!<br>";
//سازگاری با حروف فارسی
$sql = "SET NAMES 'utf8'";
$query = mysqli_query($conn, $sql);
//ساخت جدول و ستون ها
$sql = "CREATE TABLE books(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
book VARCHAR(255),
level VARCHAR(255))
ENGINE=MyISAM DEFAULT CHARACTER SET=utf8 COLLATE=utf8_persian_ci";
$query = mysqli_query($conn, $sql);
if(!$query) {
echo "Creating Table books: Error! " . mysqli_error($conn) . '<br>';
} else {
echo "Creating Table books: OK!<br>";
//ذخیره نمونه اطلاعات در جدول
$sql = "INSERT INTO books(book, level) VALUES('آموزش HTML', 'مقدماتی')";
$query = mysqli_query($conn, $sql);
$sql = "INSERT INTO books(book, level) VALUES('آموزش PHP', 'مقدماتی')";
$query = mysqli_query($conn, $sql);
$sql = "INSERT INTO books(book, level) VALUES('آموزش MySQL', 'پیشرفته')";
$query = mysqli_query($conn, $sql);
if(!$query) {
echo "Inserting Into Table books: Error! " . mysqli_error($conn);
} else {
echo "Inserting Into Table books: OK!";
}
}
}
//پایان اتصال
mysqli_close($conn);
?>
برنامه نویسی شی گرا (Object-oriented):<?php
//اتصال به دیتابیس
$conn = new mysqli("localhost", "username", "password", "dbname");
if(!$conn) {
echo "PHP & MySQL Connection: Error! " . $conn->errno . ' - ' . $conn->error;
exit;
} else {
echo "PHP & MySQL Connection: Ok!<br>";
//سازگاری با حروف فارسی
$sql = "SET NAMES 'utf8'";
$conn->query($sql);
//ساخت جدول و ستون ها
$sql = "CREATE TABLE books(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
book VARCHAR(255),
level VARCHAR(255))
ENGINE=MyISAM DEFAULT CHARACTER SET=utf8 COLLATE=utf8_persian_ci";
$conn->query($sql);
if(!$conn) {
echo "Creating Table tblname: Error! " . $conn->error;
} else {
echo "Creating Table tblname: OK!<br>";
//ذخیره نمونه اطلاعات در جدول
$sql = "INSERT INTO books(book, level) VALUES('آموزش HTML', 'مقدماتی')";
$conn->query($sql);
$sql = "INSERT INTO books(book, level) VALUES('آموزش PHP', 'مقدماتی')";
$conn->query($sql);
$sql = "INSERT INTO books(book, level) VALUES('آموزش MySQL', 'پیشرفته')";
$conn->query($sql);
if(!$conn) {
echo "Inserting Into Table books: Error! " . $conn->error;
} else {
echo "Inserting Into Table books: OK!";
}
}
}
//پایان اتصال
$conn->close();
?>
توضیح:- چنانچه پیش از این جدول books را ساخته باشیم با اجرای پرس و جوی بالا خطای
Creating Table books: Error! Table 'books' already exists
را دریافت خواهیم کرد، دلیل این خطا وجود جدول هم نام و تلاش برای ایجاد مجدد آن است، برای رفع این مشکل از طریق برنامه phpMyAdmin که معمولا در سرور مجازی با درج آدرس http://localhost/phpmyadmin
در دسترس است، جدول موجود را Drop می کنیم (اصطلاح Drop در پایگاه داده معادل حذف و Delete است).- هر دستور INSERT INTO مقادیر را در یک ردیف از ستون های تعیین شده ذخیره می کند، در این نمونه کد مقادیر به صورت مستقیم درج شده اند و از نظر امنیتی بررسی خاصی روی آنها صورت نگرفته است، در برنامه های کاربردی لازم است که هر نوع ورودی استفاده شده در پرس و جوهای دیتابیس قبل از هرچیز ایمن سازی شوند تا از نفوذ و خرابکاری احتمالی در پایگاه داده جلوگیری شود (در ادامه نکاتی که جهت حفظ امنیت دیتابیس باید رعایت کنیم را بررسی خواهیم کرد).
- در مواردی که اطلاعات به صورت مقادیر چندگانه و آرایه ای هستند بهتر است جهت مختصر نویسی و کدنویسی بهینه دستور INSERT را در حلقه ی while یا for قرار دهیم، در مثال بالا جهت جلوگیری از پیچیده شدن مبحث این کار صورت نگرفته است اما در برنامه نویسی حرفه ای تا حد امکان باید سعی کنیم مختصر و مفید کدنویسی کنیم!
- جهت سازگاری کامل جداول پایگاه داده با حروف زبان فارسی لازم است که علاوه بر تعیین utf8 به عنوان DEFAULT CHARACTER SET و utf8_persian_ci به عنوان COLLATE پیش فرض، پرس جوی زیر را هم پس از اتصال به دیتابیس اجرا کنیم:
SET NAMES 'utf8'
- فراموش نکنیم که پس از پایان اجرای پرس و جوها بهتر است از تابع mysqli_close استفاده کنیم تا از آزادسازی منابع سرور مطمئن شویم.ایمن سازی مقادیر ورودی به دیتابیس در اکستنشن MySQLi
یکی از نکات کلیدی که برنامه نویسان وب در هنگام کار با سیستم های مدیریت پایگاه داده باید حتما به آن توجه داشته باشند حفظ امنیت کدها و جلوگیری از نفوذ به دیتابیس است، از جمله روش های متداول هکرها حملات موسوم به SQL Injection یا تزریق و اضافه کردن دستورات به مقادیری است که به عنوان ورودی از سمت کاربر دریافت و در پرس و جوهای سرور جایگزین می شوند، با توجه به مقدماتی بودن سطح این سری از آموزش ها از توضیح چگونگی این حملات خودداری می کنیم و در ادامه صرفا با نحوه مقابله با آنها در اکستنشن MySQLi آشنا خواهیم شد.
نخستین گام در جهت حفظ امنیت دیتابیس عدم درج مستقیم هرگونه مقادیری است که از سمت کاربر دریافت می شود، برای این منظور در روش برنامه نویسی رویه ای (Procedural) از تابع mysqli_real_escape_string و در برنامه نویسی شی گرا (Object-oriented) از Prepared Statement و Bind Param استفاده می کنیم.
ایمن سازی پارامترها با تابع mysqli_real_escape_string
یکی از روش های متداول ایمن سازی پارامترها در برنامه نویسی رویه ای (Procedural) استفاده از تابع mysqli_real_escape_string است، با این تابع می توانیم مقادیر ورودی از سمت کاربر را قبل از استفاده در پرس و جوی دیتابیس به لحاظ وجود کاراکترهای زیر ایمن سازی کنیم:
NUL (ASCII 0)
\n
\r
\
'
"
Control-Z
این دسته از کاراکترها نباید به عنوان ورودی خام و به صورت پارامتر مستقیم در پرس و جوها استفاده شوند، به طور مثال اگر دستور INSERT در پرس و جوی ما به شکل زیر باشد://ذخیره نمونه اطلاعات در جدول
$book = 'PHP';
$level = 'pro';
$sql = "INSERT INTO books(book, level) VALUES('$book', '$level')";
و به فرض هکر مقدار متغیر level را از فرمی در صفحه HTML به این صورت ارسال کند:$level = 'pro\'';
پرس و جویی نهایی به شکل زیر (با کاراکتر ' اضافه) خواهد بود:INSERT INTO books(book, level) VALUES('PHP', 'pro'')
کمترین اتفاقی که در این حالت ممکن است رخ دهد از کار افتادن برنامه و دریافت خطای زیر است:Inserting Into Table books: Error! You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''pro'')' at line 1
بروز خطا این پیام را به هکر می دهد که ایمن سازی پارامترها در پرس و جوهای دیتابیس به درستی صورت نگرفته و کدها قابل نفوذ هستند، به همین جهت برای در امان بودن از این نوع خطرات باید قبل از استفاده از پارامترها در پرس و جو آنها را از تابع mysqli_real_escape_string عبور دهیم://ذخیره نمونه اطلاعات در جدول
$book = mysqli_real_escape_string($conn, 'PHP');
$level = mysqli_real_escape_string($conn, 'pro\'');
$sql = "INSERT INTO books(book, level) VALUES('$book', '$level')";
این تابع دو آرگیومنت دارد، آرگیومنت اول متغیر (آبجکت) اتصال است و آرگیومنت دوم مقادیری است که می خواهیم به عنوان پارامتر در پرس و جو جایگزین کنیم، برای آشنایی بیشتر با این تابع و دیدن نمونه مثال ها می توانیم به آدرس زیر در سایت php.net رجوع کنیم.php.net/manual/en/mysqli.real-escape-string.php
ایمن سازی پارامترها با Prepared Statement و Bind Param
در برنامه نویسی شی گرا (Object-oriented) علاوه بر متد mysqli_real_escape_string روش توصیه شده دیگری برای ایمن سازی پارامترها تحت عنوان Prepared Statement وجود دارد، در شیوه Prepared Statement ابتدا پرس و جو بدون ارسال پارامترهای ورودی به دیتابیس ارسال می شود (به جای پارامترها علامت ? درج می کنیم) و سپس مقادیر پارامترهای مورد نظر به صورت Bind Param به دیتابیس ارسال شده و در نهایت پرس و جوی نهایی تکمیل و اجرا می شود، با این شیوه بخش دستورات از بخش مقادیر جدا شده و بدین نحو می توانیم حملات SQL Injection را خنثی کنیم، در مثال زیر نمونه کد شی گرائی که در آموزش بررسی کردیم را در قسمت دستور INSERT به شکل زیر ویرایش می کنیم:
//ذخیره نمونه اطلاعات در جدول
$book = 'PHP';
$level = 'pro';
$sql = "INSERT INTO books(book, level) VALUES(?, ?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ss", $book, $level);
$stmt->execute();
همان طور که مشخص است به جای متد query از سه متد prepare، bind_param و execute استفاده کرده ایم، در متد prepare دستور پرس و جو بدون ارسال پارامترها درج شده است (در قسمت VALUES به جای هر پارامتر یک علامت ? جایگزین شده است)، در متد bind_param در آرگیومنت اول به ازای نوع داده (Data Type) هر پارامتر یک حرف s قرار داده ایم، s به معنی String (رشته) است، در اکستنشن MySQLi در کل چهار نوع داده به شرح زیر در قسمت Bind قابل تعریف است:i - Integer
s - String
d - Double
b - Blob
از این چهار نوع معمولا i به معنی Integer (عدد) و s به معنی String (رشته) بیشترین کاربرد را در پرس و جوها دارند.در نهایت با فراخوانی متد execute پرس و جو به نحو کامل اجرا شده و دستور INSERT اعمال می شود.
نکته: در برنامه های کاربردی معمولا مقادیر ورودی با متدهای GET یا POST از سمت کاربر دریافت شده و سپس به متغیرها نسبت داده می شوند، به طور مثال:
$book = $_POST['book'];
$level = $_POST['level'];
در صورت عدم آشنایی با نحوه دریافت پارامترها از سمت کاربر می توانیم به مبحث فرم های وب در HTML و متد GET و POST در PHP مراجعه کنیم.مطالب گفته شده در این آموزش جهت شروع آشنایی با بحث ایمن سازی پارامترها در اکستنشن MySQLi کفایت می کند، در آموزش های پیش رو با توضیحات و مثال های بیشتری از مبحث ایمن سازی پارامترها در برنامه نویسی PHP و MySQL آشنا خواهیم شد.
دسته بندی: آموزش مقدماتی » MySQL
برچسب ها: MySQL

به روز رسانی ردیف ها در MySQL با UPDATE
استفاده از WHERE در پرس و جوی MySQL
ساخت دیتابیس، جدول و ستون با دستور CREATE در MySQL
آموزش MySQL، سیستم مدیریت پایگاه داده
اتصال PHP به MySQL با اکستنشن MySQLi
دیدگاه


میثم
۲۱:۴۷ ۱۴۰۲/۰۱/۲۰
خیلی ممنونم. با تابع
html_entity_decode($text)
مشکل نمایش حل شد.میثم
۱۹:۰۸ ۱۴۰۲/۰۱/۲۰
ممنونم. خیلی لطف کردین.
ببخشید میشه به صورت خلاصه در مورد Prepared Statement و Bind Param یه توضیح بدین. همچنین من وقتی اطلاعات رو با تابع ذکر شده در بالا ذخیره میکنم ، موقع نمایش ، تمام تگ ها هم به صورت متن چاپ میشه در صورتی که قاعدتاً باید به صورت یه html امن چاپ بشه تا مثلاً اگه رنگ متن در ادیتور قرمز شده، در خروجی هم قرمز نمایش داده بشه. و اگه مثلاً تگ اسکریپت داشت، عمل نکنه. برای رفع این مشکل باید از چه تابعی استفاده کنم که امن هم باشه؟
ببخشید میشه به صورت خلاصه در مورد Prepared Statement و Bind Param یه توضیح بدین. همچنین من وقتی اطلاعات رو با تابع ذکر شده در بالا ذخیره میکنم ، موقع نمایش ، تمام تگ ها هم به صورت متن چاپ میشه در صورتی که قاعدتاً باید به صورت یه html امن چاپ بشه تا مثلاً اگه رنگ متن در ادیتور قرمز شده، در خروجی هم قرمز نمایش داده بشه. و اگه مثلاً تگ اسکریپت داشت، عمل نکنه. برای رفع این مشکل باید از چه تابعی استفاده کنم که امن هم باشه؟
خواهش، در خصوص ایمن سازی لطفا عبارت "ایمن سازی پارامترها با Prepared Statement و Bind Param" را در قسمت جستجوی سایت وارد کنید در مطلب نحوه ذخیره اطلاعات در دیتابیس به صورت مختصر در این خصوص توضیح داده ایم، برای اطلاعات تکمیلی و دیدن نمونه کدهای بیشتر لطفا در وب جستجو کنید، در خصوص مشکل مطرح شده احتمالا کدهای شما دوباره تبدیل می شوند (ممکن است یک مرحله در سطح ادیتور این تبدیل صورت گرفته باشد)، سورس سایتتان را با سایت های دیگر تطبیق دهید ببینید تفاوتی می کند یا خیر (به طور خاص کاراکترهای <>) یا در صورت تمایل یک نمونه سورس از خروجی بخش کدهای سایت درج کنید تا بررسی کنیم.
میثم
۱۶:۱۵ ۱۴۰۲/۰۱/۲۰
سلام بر شما استاد عزیز.
دو تا سوال خدمت شما داشتم.
1- من قصد دارم برای فرم حاوی textarea در سایتم از ckeditor استفاده کنم. ckeditor خروجی html میده که ممکنه برای حملات SQL خطرناک باشه. تحقیق کردم که استفاده از تابع زیر قبل از ذخیره کردن اطلاعات در دیتابیس برای رفع خطر مناسبه و خیال ادمو راحت میکنه.
خواستم ببینم برای رفع خطر کدام رو ترجیح میدین؟ و اگه از هر دو استفاده کنیم بهتر نیست ؟ مثل زیر :
فرق بین
دو تا سوال خدمت شما داشتم.
1- من قصد دارم برای فرم حاوی textarea در سایتم از ckeditor استفاده کنم. ckeditor خروجی html میده که ممکنه برای حملات SQL خطرناک باشه. تحقیق کردم که استفاده از تابع زیر قبل از ذخیره کردن اطلاعات در دیتابیس برای رفع خطر مناسبه و خیال ادمو راحت میکنه.
function dataready($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
جای دیگه خواندم که استفاده از تابع mysqli_escape_string();
به تنهایی کافیه.خواستم ببینم برای رفع خطر کدام رو ترجیح میدین؟ و اگه از هر دو استفاده کنیم بهتر نیست ؟ مثل زیر :
function CleanEditor($string){
$string = trim($string);
$string = stripslashes($string);
$string = htmlspecialchars($string);
$string = mysqli_escape_string($string);
return $string;
}
سوال دوم:فرق بین
mysqli_escape_string
و mysqli_real_escape_string
چیه؟بحث حفظ امنیت برنامه ها با توجه به شیوه های هک به دو مرحله ذخیره سازی/به روزرسانی/انتخاب اطلاعات دیتابیس (SQL Injection) و چاپ در خروجی صفحات وب (Cross-Site Scripting یا XSS) تقسیم می شود، در هنگام ذخیره سازی اطلاعات ادیتورها در دیتابیس بهترین روش توصیه شده استفاده از Prepared Statement و Bind Param است که به طور کلی خیالمان از بابت ایمن بودن فرایندها راحت می شود، اما به عنوان روش به اصطلاح دم دستی و یا در برنامه نویسی رویه ای می توانیم از تابع mysqli_real_escape_string در هنگام ذخیره سازی/به روزرسانی/انتخاب اطلاعات دیتابیس و htmlspecialchars یا strip_tags در هنگام چاپ خروجی استفاده کنیم، تابع تکمیلی شما مشکلی ندارد منتها استفاده از htmlspecialchars برای دفع حملات XSS است و این حملات در مرحله چاپ خروجی در صفحه وب عمل می کنند (به فرض اجرای تگ اسکریپت مخربی که هکر قبلا به محتوای ذخیره شده در دیتابیس ما افزوده است) پس مهم این است که خروجی ما ایمن باشد و به فرض تگ های script را خنثی نشده چاپ نکنیم، بحث دیگر برای تابع mysqli_real_escape_string اینکه باید آبجکت اتصال به دیتابیس را هم به عنوان پارامتر اول این تابع تنظیم کنیم در غیر اینصورت مفسر خطا می دهد، در مورد سوال آخر با توجه به اطلاعات سایت php.net به عنوان مرجع mysqli_escape_string تابع alias و مترادف mysqli_real_escape_string است و تفاوتی با هم ندارند، استفاده از حالت real متداول است.
This function is an alias of: mysqli_real_escape_string().
https://www.php.net/manual/en/function.mysqli-escape-string.php
۱۶:۳۶ ۱۳۹۹/۱۰/۰۸
سلام
من یه فرمی طراحی کردم که توش قراره تعداد زیاد (حدود 10 الی 50) فیلد رو تو دیتابیس اینسرت کنم.
آیا باید به کمک حلقه چندین مرتبه دستور اینسرت رو اجرا کنم یا راه دیگری هست که بشه مثلا 50 تا رکورد رو یکجا اینسرت کرد به دیتابیس.
البته بدون ایکسل. می خوام از داخل صفحه فرم html این کار رو انجام بدم.
ممنون می شم راهنمایی بفرمایید
من یه فرمی طراحی کردم که توش قراره تعداد زیاد (حدود 10 الی 50) فیلد رو تو دیتابیس اینسرت کنم.
آیا باید به کمک حلقه چندین مرتبه دستور اینسرت رو اجرا کنم یا راه دیگری هست که بشه مثلا 50 تا رکورد رو یکجا اینسرت کرد به دیتابیس.
البته بدون ایکسل. می خوام از داخل صفحه فرم html این کار رو انجام بدم.
ممنون می شم راهنمایی بفرمایید
با توجه به قسمت اول سوال در صورتی که فرم شما شامل فیلدهای یکتا است (به فرض از فیلد نام، سن، شماره تماس و... صرفا یک مورد وجود دارد) تعداد آنها مهم نیست و می توانیم در یک پرس و جوی INSERT تمام فیلدها را در یک ردیف در جدول ذخیره کنیم، اما اگر منظور از قسمت دوم سوال ایجاد چندین ردیف در جدول با اطلاعات مختلف از فیلدهای هم نام در فرم است (به فرض چندین فیلد نام در فرم ارسالی وجود دارد) در اینصورت ورودی از سمت HTML باید به شکل آرایه باشد یعنی در قسمت name علامت [] درج شده باشد، مثال:
<form action="#" method="post">
<input type="text" name="input_name[]">
<input type="text" name="input_name[]">
<input type="text" name="input_name[]">
<input type="text" name="input_name[]">
<input type="submit" value="submit">
</form>
در این حالت باید در کدهای PHP در حلقه فیلدها را مورد به مورد با دستور INSERT وارد دیتابیس کنیم یا اینکه قسمت VALUE پرس و جو را در حلقه آماده سازی و با یک دستور INSERT در خارج از حلقه اطلاعات را وارد کنیم، مثال (تست نشده!):<?php
$name = @$_POST['input_name'];
for($i = 0; $i < count($name); $i++){
//INSERT INTO tbl(col) VALUES("$name[$i]");
}
?>
یا<?php
$name = @$_POST['input_name'];
$values = '';
for($i = 0; $i < count($name); $i++){
$values .= '("' . $name[$i] . '")';
if($i < (count($name) - 1)){
$values .= ',';
}
}
//INSERT INTO tbl(col) VALUES $values;
?>
کدهای بالا صرفا ساختار کلی را نمایش می دهند، قاعدتا برای استفاده کاربردی از آنها باید متناسب با اکستنشن مورد استفاده دستور INSERT را تنظیم کنیم.امین
۰۳:۱۲ ۱۳۹۸/۱۱/۰۲
سلام تشکر بابت راهنماییتون. منظور من این بود که: الان با ثبت نام کاربر a در سایت اطلاعاتش در دیتابیس ثبت میشه و یک پوشه با فایل های index و فایل های دیگه ایجاد میشه. همراه این فایل ها که درون پوشه ای که نام کاربر هست ایجاد میشه، یک فایل هست که کاربران مهمان میتونن با فرمی که در اون صفحه وجود داره برای کاربر a پیام بفرستن. یعنی جوری که نام کاربر a ثبت شده موقع ثبت پیام و یا اینکه پیام کاربر مهمان در جدولی که موقع ثبت نام کاربر a ایجاد شده ثبت بشه که داخل پنل کاربر a پیام های مربوط به خودش نمایش داده بشه! امیدوارم متوجه منظورم شده باشین و ممنون بابت وقتی که میذارین♥
دسترسی به اسکریپت نداریم که ببینیم ساختار دقیقا به چه نحوی است اما در کل برای اینگونه موارد نیاز به یک پارامتر شناسایی دارید، یعنی به نحوی کاربران مختلف باید از هم شناسایی شوند تا بتوانیم اطلاعات هر کاربر را با نام او ذخیره کنیم، با توجه به توضیحات نام دایرکتوری همان نام کاربر است و لذا در آدرس URL باید موجود باشد، به فرض:
شناسایی کاربران از هم می تواند با توجه به کدهای اسکریپت از شیوه های دیگر مثل سشن یا توابع خود برنامه باشد، در کل باید اسکریپت دقیقا بررسی شود تا بتوانیم راه حل کاربردی ارائه کنیم، در صورت تمایل می توانید از طریق ایمیل سایت (موجود در بخش تماس) موضوع را جهت بررسی با برنامه TeamViewer مطرح و پاسخ را از همان طریق پیگیری کنید.
example.com/admin/comment.php
در اینجا می توانیم برای استخراج پارامتر دوم (نام admin) کد بنویسیم و این نام را در فیلد hidden در فرم ارسال پیام قرار داده و به همراه سایر اطلاعات به سرور ارسال نمائیم، در سرور هم در جدول پیام ها در یک ستون نام کاربر را درج و به هنگام فراخوانی، اطلاعات هر کاربر را برای او SELECT می کنیم.شناسایی کاربران از هم می تواند با توجه به کدهای اسکریپت از شیوه های دیگر مثل سشن یا توابع خود برنامه باشد، در کل باید اسکریپت دقیقا بررسی شود تا بتوانیم راه حل کاربردی ارائه کنیم، در صورت تمایل می توانید از طریق ایمیل سایت (موجود در بخش تماس) موضوع را جهت بررسی با برنامه TeamViewer مطرح و پاسخ را از همان طریق پیگیری کنید.
امین
۱۴:۱۸ ۱۳۹۸/۱۰/۳۰
سلام خسته نباشید یه اسکریپت دارم که وقتی کاربر ثبت نام میکنه یه پوشه و محتواش ایجاد میشه. میخوام یه صفحه با هر ثبت نام ایجاد بشه که داده ها داخل جدول همون کاربر ذخیره بشه، مثل پیام دادن در صفحه ای که موقع ثبت نام ایجاد شده. میشه راهنمایی بفرمایید
باید ابتدا دیتابیس، جدول و ستون های مد نظرتان را در MySQL و به کمک برنامه نویسی PHP یا برنامه phpMyAdmin ایجاد کنید، سپس بخش ثبت نام اسکریپت را ویرایش کرده و کدهای ذخیره اطلاعات در دیتابیس را به آن اضافه کنید، برای نمایش اطلاعات نیز می توانید پرس و جوی SELECT بنویسید، در کل باید با PHP آشنا باشید و حتی المقدور یک دوره مقدماتی کار با MySQL را بگذرانید تا امکان ویرایش صحیح اسکریپت میسر شود.
نکته: در آموزش های کاربردی MySQL سایت مطلبی در خصوص نحوه طراحی فرم ثبت نام و عضویت کاربر وجود دارد که می تواند کمک کند.
نکته: در آموزش های کاربردی MySQL سایت مطلبی در خصوص نحوه طراحی فرم ثبت نام و عضویت کاربر وجود دارد که می تواند کمک کند.
zeynab
۱۷:۰۶ ۱۳۹۸/۰۵/۲۸
سلام
یه سوال دارم
برای اینکه بتونم رنگ رو ذخیره کنم تو جدولم در قسمت پایگاه داده چیکار باید کنم ؟؟
من الان رنگ با توجه به مختصاتی که از عکس میدم چاپ میشه, ولی نمیتونم ذخیره اش کنم
ممنون میشم راهنماییم کنین.......
یه سوال دارم
برای اینکه بتونم رنگ رو ذخیره کنم تو جدولم در قسمت پایگاه داده چیکار باید کنم ؟؟
من الان رنگ با توجه به مختصاتی که از عکس میدم چاپ میشه, ولی نمیتونم ذخیره اش کنم
ممنون میشم راهنماییم کنین.......
با توجه به ساختار برنامه ممکن است مراحل کار متفاوت باشد اما در مجموع اگر بتوانید مقادیر را در صفحه مرورگر چاپ کنید قاعدتا امکان ذخیره سازی آنها در دیتابیس نیز وجود دارد، با فرض اینکه مقادیر صرفا در صفحه مرورگر در دسترس هستند می توانید آنها را به فیلد های input در فرم HTML نسبت داده و با ارسال فرم (با شیوه Ajax یا حالت معمولی) به سرور ارسال و در سرور با برنامه نویسی PHP دریافت و در دیتابیس ذخیره کنید.
برای انجام صحیح این مراحل تا حدودی به تسلط بر جاوا اسکریپت نیاز خواهید داشت.
برای انجام صحیح این مراحل تا حدودی به تسلط بر جاوا اسکریپت نیاز خواهید داشت.
کیهان
۱۱:۰۰ ۱۳۹۸/۰۵/۱۴
سلام دوستان
من یک صفحه درست کردم که از طریق یک فرم اطلاعات رو میفرسته به این صفحه برای ذخیره در دیتابیس
ولی متاسفانه فقط یک مرتبه اونهم وقتی جدول خالی باشه اطلاعات ذخیره میشن
ممنون میشم کمکم کنید
بعد در این صفحه خطای زیر رو
من یک صفحه درست کردم که از طریق یک فرم اطلاعات رو میفرسته به این صفحه برای ذخیره در دیتابیس
ولی متاسفانه فقط یک مرتبه اونهم وقتی جدول خالی باشه اطلاعات ذخیره میشن
ممنون میشم کمکم کنید
<?php $name=$_POST['std-name'];
$lname=$_POST['std-lname'];
$fname=$_POST['std-fname'];
$stdid1=$_POST['std-id1'];
$stdid2=$_POST['std-id2'];
$stdtt=$_POST['std-tt'];
$stdpschool=$_POST['std-pschool'];
$stdpavg=$_POST['std-pavg'];
$stdphone=$_POST['std-phone'];
$stdmname=$_POST['std-mname'];
$stdclassid=$_POST['std-classid'];
$stdex=$_POST['std-ex'];
$stdfphone=$_POST['std-fphone'];
$stdmphone=$_POST['std-mphone'];
$filename=$_FILES["std-img"]["name"];
$filename_array = explode('.', $filename);$tmp=end($filename_array);
$stdimg = $stdid1 . '.' . $tmp;move_uploaded_file($_FILES["std-img"]["tmp_name"],"upload/" . $stdimg);
$img="upload/" . $stdimg;
$db=new PDO("mysql:host=localhost;dbname=fazilat","root"," ");
$db->exec( "SET CHARACTER SET utf8" );
$select="SELECT * FROM student WHERE `STD-ID`='$stdid1'";$stmt1=$db->prepare($select);$stmt1->execute();$num1=$stmt1->rowCount();
if($num1>0){echo 'دانش آموز با این شماره دانش آموزی قبلا ثبت شده است';} else{ $sql="INSERT INTO student (`STD-ID`, `NAME`, `L-NAME`, `F-NAME`, `T.T.`, `ID` , `PRE-SCHOOL` , `PRE-AVG` ,`EX-ACTIVITIES` ,`CLASS-ID` ,`M-NAME` ,`IMG` ,`PHONE` ,`FATHER-PHONE` ,`MOTHER-PHONE`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
$stmt=$db->prepare($sql);
$result = $stmt->execute(array($stdid1, $name , $lname , $fname , $stdtt , $stdid2 , $stdpschool , $stdpavg , $stdex , $stdclassid , $stdmname , $img , $stdphone , $stdfphone , $stdmphone));
if ( false===$result ) { die('execute() failed: ' . htmlspecialchars($stmt->error));
print $result->errorCode(); } }?>
توضیح : درصفحه اول تو تگ فرم مقادیر رو میگیره و به این صفحه ارسال میکنهبعد در این صفحه خطای زیر رو
1die('execute() failed: ' . htmlspecialchars($stmt->error));
میده و هیچ چیز در جدول ثبت نمیکنهقسمت آخر کدی که درج کرده اید وظیفه نمایش خطاهای دریافتی را بر عهده دارد و باید متن خطا را در خروجی چاپ کند تا مشکل کار مشخص شود، منتها ظاهرا با اجرای برنامه به جای نمایش خطا خود کد در خروجی چاپ می شود لذا به احتمال قوی در کدنویسی صفحه خطای Syntax وجود دارد و به فرض بخشی از برنامه ناقص است یا مواردی اضافه در کدنویسی درج شده است، راه حل نهایی رفع مشکل نمایش خطای دریافتی یا دسترسی به سورس کدها و امکان خطایابی کلی برنامه است.
کورش بیات
۲۳:۵۳ ۱۳۹۸/۰۳/۰۱
سلام وقت بخیر
من در دستور insert خطا دارم
درواقع کد رو مینویسم که داده رو ذخیره کنه ذخیره نمیکنه و حتی در php storm هم روش موس میبری خطا رو نشون میده
عیناً شبیه آموزش این مراحل رو میرم ولی خطا دارم
من در دستور insert خطا دارم
درواقع کد رو مینویسم که داده رو ذخیره کنه ذخیره نمیکنه و حتی در php storm هم روش موس میبری خطا رو نشون میده
$mycnn=mysqli_connect('localhost:3306','root','','kourosh');
$sqlquery="INSERT INTO 'internal' ('username','password') VALUES('$username,$password')";
mysqli_query($mycnn,$sqlquery);
خطا:No data source are configured...
چه باید کرد؟عیناً شبیه آموزش این مراحل رو میرم ولی خطا دارم
خطا در برنامه PhpStorm نمایشی و مربوط به تنظیمات این برنامه است و دلیل عدم اجرای پرس و جو نیست، پرس و جو خطای Syntax دارد و مطابق با آموزش نیست (در استفاده از علامت ' برای ستون و مقادیر مشابه قسمت INSERT در آموزش عمل کنید).
رسول فلاح
۱۶:۴۰ ۱۳۹۷/۱۲/۱۷
سلام
سوالی خدمت شما داشتم
اگر بخوایم وقتی کاربر سفارشی رو ثبت می کنه در حالی که صفحه سفارش های ثبت شده در پنل مدیریت باز است پیامی برای مدیر نشان داده بشه چه باید کرد؟
من نمی خوام صفحه برای مدیر رفرش بشه بلکه به محض اینکه شفارش ثبت شد یک اعلان برای مدیر نشان داده بشه تا متوجه بشه که سفارشی ثبت شده
سوالی خدمت شما داشتم
اگر بخوایم وقتی کاربر سفارشی رو ثبت می کنه در حالی که صفحه سفارش های ثبت شده در پنل مدیریت باز است پیامی برای مدیر نشان داده بشه چه باید کرد؟
من نمی خوام صفحه برای مدیر رفرش بشه بلکه به محض اینکه شفارش ثبت شد یک اعلان برای مدیر نشان داده بشه تا متوجه بشه که سفارشی ثبت شده
برای دریافت اطلاعات از سرور بدون رفرش صفحه باید از Ajax استفاده کنید، در سمت کاربر یک تابع بنویسید که به فرض هر چند ثانیه درخواست را به سرور ارسال و پاسخ را دریافت کند، در سمت سرور نیز با کدنویسی PHP وضعیت دیتابیس را بررسی نمائید، آموزش های مربوطه در این خصوص در سایت در دو سطح مقدماتی و کاربردی وجود دارد.
حسین
۱۳:۲۷ ۱۳۹۶/۱۲/۲۶
سلام من میخواسم یه فلیدهایی مثل input ایجاد کنم و اطلاعات وارد شده را در آن ها در یک صفحه دیگه ایجاد بشه
سوالتان واضح نیست! فیلد input را می توانید با تگ form و ملحقات آن در HTML ایجاد کنید اما برای ذخیره اطلاعات باید برنامه نویسی PHP و MySQL را فرا گرفته باشید.
محمد
۱۲:۰۰ ۱۳۹۶/۱۲/۲۶
سلام میخواستم بپرسم در کد های زیر دقیقا چه اشکالی وجود داره که مقدار های ایمیل و پسورد رو ارسال نمیکنه
<?php
if (isset($_POST['register'])){
$email = $_POST['email'];
$password = $_POST['password'];
$passwordconf = $_POST['password-conf'];
if ($password != $passwordconf){
echo 'پسورد و تکرار با هم مطابقت ندارند';
}else{
mysql_query($conn, "INSERT INTO users (email, password) VALUES ($email, $password)");
echo 'ثبت نام شما با موفقیت انجام شد';
}
}
و چنین خطایی رو میدهFatal error: Uncaught Error: Call to undefined function mysql_query() in C:\xampp\htdocs\froshgah\users\register.php:32 Stack trace: #0 {main} thrown in C:\xampp\htdocs\froshgah\users\register.php on line 32
در اون جا نوشته خط 32 که مربوط به کدmysql_query($conn, "INSERT INTO users (email, password) VALUES ($email, $password)");
میشه اما من خطاییی نمیبینمخطای دریافتی مربوط به فعال نبودن اکستنشن MySQL در تنظیمات PHP است، با توجه به تاریخ نگارش مطلب در کدهای جدید بهتر است از اکستنش MySQLi استفاده کنید که جایگزین MySQL شده است و آموزش های آن در وب وجود دارد (آموزش های سایت نیز به مرور در حال به روزرسانی در همین راستا می باشند)، اگر به هر دلیل همچنان می خواهید از اکستنش قدیمی استفاده کنید باید آن را از تنظیمات سرور یا لوکال هاست فعال نمائید.
پرستو
۱۲:۵۰ ۱۳۹۶/۱۱/۲۸
سلام. ممنون از سایت خوبتون
من هر کاری میکنم سایتم به دیتابیس لوکال متصل نمیشه! از درستی کدها مطمئنم. وقتی فایل رو تو مرورگر باز میکنم یا خود کدهایی که نوشتم و نمایش میده یا اصلا هیچ کاری انجام نمیشه و هیچی نمایش داده نمیشه
من هر کاری میکنم سایتم به دیتابیس لوکال متصل نمیشه! از درستی کدها مطمئنم. وقتی فایل رو تو مرورگر باز میکنم یا خود کدهایی که نوشتم و نمایش میده یا اصلا هیچ کاری انجام نمیشه و هیچی نمایش داده نمیشه
با توجه به توضیحات ظاهرا سرور مجازی شما فعال و در حال اجرا نیست، ابتدا باید مطمئن شوید که برنامه سرور مجازی به درستی نصب شده و فعال باشد، برای این کار دستور PHP زیر را در یک فایل نوشته، در دارکتوری www قرار داده و از طریق مرورگر آن را اجرا کنید، اگر خروجی برابر با 1 باشد یعنی سرور شما فعال است، در غیر این صورت باید مشکل از فعال نبودن برنامه باشد.
<?php
echo 1;
?>
در صورت فعال بودن سرور مجازی می توانید مشکلات مربوط به دیتابیس (ساخت دیتابیس، اختصاص کاربر به دیتابیس، ساخت جدول و ستون، اطلاعات اتصال، کدهای نوشته شده و...) را خطایابی کنید.سحر
۱۴:۵۱ ۱۳۹۶/۰۴/۲۹
سلام... من میخوام 3 رکورد آخر جدول رو در php استخراج کنم میشه کوئریشو نشونم بدید؟
برای استخراج آخرین اطلاعات از دیتابیس کافی است از ORDER BY در کنار LIMIT استفاده کنید:
SELECT * FROM table ORDER BY id DESC LIMIT 3
مسعود
۱۷:۳۵ ۱۳۹۵/۱۰/۲۴
با سلام
دستوراتی که در بالا گفتین در سیستم من می بایست به این روش فراخوانی بشه
راه حلی داره که بتونم با مثه دستورات شما از دیتابیسم خروجی بگیرم
دستوراتی که در بالا گفتین در سیستم من می بایست به این روش فراخوانی بشه
$connect = mysqli_connect("localhost","rejister","rejister","learn1-2") or die(mysql_error());
$username = $_POST['username'];
$password = $_POST['password'];
$mobile = $_POST['mobile'];
$email = $_POST['email'];
$cuntry = $_POST['cuntry'];
$city = $_POST['city'];
mysqli_query($connect,"INSERT INTO `rejister` (`username`,`password`,`mobile`,`email`,`cuntry`,`city`)
VALUES('".$username."','".$password."','".$mobile."','".$email."','".$cuntry."','".$city."')");
به نظر شما مشکل از نرم افزار زمپ من هست یا مشکل سخت افزاریه؟؟راه حلی داره که بتونم با مثه دستورات شما از دیتابیسم خروجی بگیرم
در کدهای شما از اکستنشن MySQLi استفاده شده لذا شما باید با این اکستنشن و تفاوت آن با MySQL آشنا باشید (لطفا در این رابطه در وب جستجو نمائید)، با اندکی تغییر در دستورات می توانید همین آموزش را با MySQLi پیاده سازی کنید.
- به سوالات کلی، زمانبر، مبهم و مشکلاتی که تلاشی برای رفع آنها نکرده باشید پاسخ مختصر داده شده یا به بخش برنامه نویسی اختصاصی ارجاع داده می شوند.
- کدها و اسکریپت های طولانی را ترجیحا در یک صفحه وب آنلاین یا به صورت حساب موقت و آزمایشی قرار دهید تا امکان بررسی دقیق مشکل و خطایابی میسر باشد.
- تمام دیدگاه های ارسالی خوانده شده و برای هر کاربر مدت زمان لازم جهت پاسخگویی در نظر گرفته می شود، لطفا از طرح سوالات متعدد در بازه زمانی کوتاه خودداری کنید.