شنبه ۲۲ شهریور ۱۴۰۴

Saturday, September 13, 2025 GMT +3:30

نمایش نتایج پایگاه داده MySQL با PHP و ای جکس (Ajax)

ajax-code

همانطور که در بخش آموزش های مقدماتی ای جکس (Ajax) اشاره شد، یکی از کاربردهای استفاده از این تکنیک در صفحات وب رد و بدل کردن اطلاعات بین مرورگر و سرور بدون نیاز به رفرش صفحه است، به عبارتی تمام فعل و انفعالات در پس زمینه انجام شده و در سمت کاربر (مرورگر) تقریبا جزء نمایش نتایج اتفاق خاصی رخ نمی دهد و کاربر در حالت معمول متوجه چگونگی این فرآیند نیز نمی شود و می تواند به ادامه پیمایش صفحه بپردازد که به این حالت در اصطلاح درخواست غیرهمزمان (Asynchronous) یا هم روند می گویند، در این مطلب نیز کدی کاربردی را قرار داده ایم که به کمک آن می توانیم به صورت غیرهمزمان پس از انتخاب گزینه ای از لیست باز شونده، تابعی جاوا اسکریپتی را در رویداد onchange اجرا کرده و درخواست مبتنی بر Ajax را به فایل PHP ارسال نمائیم، سپس نتیجه را از این فایل یا با اتصال به پایگاه داده MySQL دریافت کرده و در سمت کاربر به هر صورت که مورد نیاز برنامه باشد نمایش دهیم.

کد HTML و ای جکس (Ajax) سمت کاربر


پیشتر در بخش آموزش های مقدماتی Ajax گفتیم که برای ارسال درخواست از صفحه مرورگر (سمت کاربر) به فایل PHP (سمت سرور) ابتدا نیاز به کدهای HTML، دستورات جاوا اسکریپت و متدهای Ajax است، هرچند درخواست Ajax را می توان به صورت مستقیم نیز تنظیم کرد اما کدهای HTML سمت کاربر معمولا شامل عناصری مانند تگ های زیرمجموعه فرم (select, input و...) یا لینک ها هستند که با انتخاب یک گزینه توسط کاربر، یک تابع در جاوا اسکریپت فراخوانی و با اجرای تابع درخواست بر بستر Ajax شکل گرفته و به سرور ارسال می شود، در زیر یک نمونه از این دستورات را درج کرده ایم که مربوط به تگ select و رویداد onchange است:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>وبگو | نمایش نتایج پرس و جو از دیتابیس با ای جکس</title>
<!-- Webgoo.ir -->
<script type="text/javascript">
function showList(str, id){
    var xmlHttp;
    if(str == ''){
        document.getElementById(id).innerHTML = '';
        return false;
    }
    if(window.XMLHttpRequest){
        //IE7+, Firefox, Chrome, Opera, Safari
        xmlHttp = new XMLHttpRequest();
    } else{
        //IE6, IE5
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    xmlHttp.onreadystatechange = function(){
        if(xmlHttp.readyState == 4){
            document.getElementById(id).innerHTML = xmlHttp.responseText;
        }
    }
    xmlHttp.open("GET", "getlist.php?q=" + str, true);
    xmlHttp.send();
}
</script>
<style type="text/css">
body{
    font-family: Tahoma, Geneva, sans-serif;
    font-size: 12px;
    direction: rtl;
}
</style>
</head>
<body>
<form action="">
<select name="list" onchange="showList(this.value, 'show-text')">
<option value="">انتخاب یک کاربر</option>
<option value="user_1">کاربر 1</option>
<option value="user_2">کاربر 2</option>
<option value="user_3">کاربر 3</option>
</select>
</form>
<br>
<div id="show-text">پس از انتخاب یک کاربر، اندکی صبر نمائید تا پاسخ از سرور دریافت شود.</div>
</body>
</html>
توضیح:
- برای شروع تابع showList را نوشته ایم تا درخواست های Ajax را از کاربر گرفته و توسط این تابع مدیریت کنیم.
- در فرم HTML و تگ select، با رویداد onchange مقادیر انتخابی کاربر به همراه آی دی بلاک div را به تابع showList ارسال می کنیم.
- متد getElementById عنصر HTML را بر اساس آی دی آن انتخاب می کند که در اینجا بلاک div با آی دی فرضی show-text به عنوان آرگیومنت به تابع و در نتیجه به این متد داده شده، در کنار این متد از متد innerHTML برای مقداردهی به بلاک هدف استفاده می کنیم.
- متغیری که در درخواست ما مقادیرش به سرور فرستاده می شود q نام دارد (=getlist.php?q)، متد استفاده شده نیز GET است که پیش از این در آموزش های مقدماتی Ajax در خصوص آن صحبت کرده ایم.

کد PHP و دستورات MySQL سمت سرور


پس از نوشتن کدهای HTML، دستورات جاوا اسکریپت و Ajax، فایلی با نام فرضی getlist.php ایجاد و کدنویسی مورد نظر جهت دریافت درخواست ارسال شده با متد GET را در آن تنظیم می نمائیم، این کد نویسی می تواند به صورت استاتیک و بدون پایگاه داده یا به صورت داینامیک و به همراه پرس جو از پایگاه داده MySQL باشد که این موضوع بستگی به هدف و نیاز برنامه ما دارد، در نمونه کدهای زیر هر دو صورت جهت راهنمایی بیشتر درج شده.
نمونه کد PHP بدون دیتابیس:
<?php
@$user = $_GET['q'];
if($user == 'user_1'){
    echo '<table width="200" border="1">
  <tr>
    <th>کاربر یک</th>
    <td>نام کاربر یک</td>
  </tr>
</table>'
;
}
elseif($user == 'user_2'){
    echo '<table width="200" border="1">
  <tr>
    <th>کاربر دو</th>
    <td>نام کاربر دو</td>
  </tr>
</table>'
;
}
elseif($user == 'user_3'){
    echo '<table width="200" border="1">
  <tr>
    <th>کاربر سه</th>
    <td>نام کاربر سه</td>
  </tr>
</table>'
;
}
?>
توضیح:
- در فایل getlist.php درخواست ارسال شده از سمت کاربر با متد GET را پردازش می کنیم.
- در اینجا صرفا به دلیل جنبه آموزشی و ساده تر شدن کدنویسی از دستورات شرطی استفاده شده، قاعدتا همین کد را می توانیم با دستور switch و case نیز بنویسیم.
نمونه کد PHP و استفاده از دستورات MySQL:
<?php
@$user = $_GET['user'];
$conn = mysqli_connect("localhost", "username", "password", "dbname");
if(!$conn){
    echo "Error!: " . mysqli_connect_errno() . ' - ' . mysqli_connect_error();
    exit;
} else{
    $user = mysqli_real_escape_string($conn, $user);
    $result = mysqli_query($conn, "SELECT id, name FROM users WHERE user = $user LIMIT 1");
    //Error
    if(!$result){
        echo 'MySQL Error: ' . mysqli_error($conn);
        die('بروز خطا در اجرای پرس و جوی MySQL');
    } //Ok
    else{
        while ($row = mysqli_fetch_assoc($result)){
            echo '<table width="200" border="1">
            <tr>
            <th>کاربر '
. $row['id'] . '</th>
            <td>نام کاربری '
. $row['name'] . '</td>
            </tr>
            </table>'
;
        }
    }
}
mysqli_close($conn);
?>
توضیح:
- در نمونه کد بالا از اکستنشن mysqli به شیوه کدنویسی معمولی (شکلی یا Procedural) استفاده کرده ایم.
- نام جدول و ستون ها فرضی و صرفا جهت نمونه است.
پیش نمایش
دسته بندی: آموزش کاربردی » Ajax
related مطالب بیشتر:
ارسال اطلاعات فرم با ای جکس (Ajax) و نمایش پیام در حال پردازش
نمایش داینامیک و صفحه به صفحه مطالب با ای جکس (Ajax)
نمایش زنده آمار و اطلاعات با ای جکس (Ajax)
آموزش نحوه آپلود فایل با PHP و ای جکس (Ajax)
ساخت قابلیت امتیازدهی با PHP و Ajax
دیدگاه
more ۳۷ دیدگاه برای این مطلب ارسال شده است.
more چینش دیدگاه ها به ترتیب از جدیدترین به قدیمی ترین است.
کاظم
۰۰:۲۲ ۱۴۰۱/۰۱/۰۳
سلام و خدا قوت
من یه ستون اضافه کردم در دیتابیس که یه سری اطلاعات رو از کاربر می گیره.
<option value="s1">s1</option> 
وقتی option رو تغییر میدم و مقدار value رو از دیتابیس میگیرم ولی اطلاعات رو از کوئری دیتابیس نمی گیره و خروجی نشون داده نمیشه.
$result = mysqli_query($conn, "SELECT * FROM multiple_image WHERE typemostanad='$user' ");
ممنون میشم راهنمایی کنید
از نمونه کدهای درج شده ایراد خاصی قابل تشخیص نیست، نحوه تغییر option نامشخص است، خروجی اصلی دیتابیس در حلقه while چاپ می شود که متاسفانه مشخص نکرده اید این قسمت از کدها به چه شکلی است، در مجموع بدون وجود کل کدها و امکان تست و خطایابی واقعی نمی شود توصیه خاصی داشت، در صورت تمایل می توانید کدهای برنامه را به نحوی که به صورت مستقل قابل اجرا باشد به آدرس ایمیل ما (موجود در بخش تماس) ارسال کنید تا بررسی کنیم.
amir
۲۰:۴۵ ۱۳۹۹/۰۲/۳۰
سلام ممنون از سایت خوبتون
چطور میشه با جاوااسکریپت ایجکس و پی اچ پی بتونم تمامی جدول های دیتابیس رو هر کدوم با یه تگ span نشون بدم و با ایجکس اپدیت کنم خیلی وقته دنبال همچین کدی میگردم
منظورم اینه که جدول ها رو از دیتابیس بگیرم و هر جدول رو داخل یک تگ اسپن قرار بدم؟
همین نمونه ساختار در این آموزش برای استخراج و نمایش اطلاعات استفاده شده است منتها به جای تگ span از table استفاده کرده ایم، در واقع شاید هیچ کد آماده ای پیدا نکنید که دقیقا مطابق هدفتان باشد مهم این است اصول مقدماتی را بدانید در این صورت هر طور که تمایل داشته باشید می توانید با برنامه نویسی ایده را به واقعیت تبدیل کنید، توصیه می کنیم آموزش های مقدماتی بخش Ajax و MySQL را مطالعه کنید.
هادی
۱۲:۴۶ ۱۳۹۶/۰۴/۱۱
درود مجدد
لینک فایل های بالا را بصورت تست براتون آپلود کردم ممنون میشم بررسی نمایید
حذف شد
منظورتان دقیقا مشخص نیست چون دو بخش دقیقا شبیه هم هستند و هیچ وجه تمایزی ندارند؟! به هر صورت برای اینکه نتیجه در جای خود خروجی داده شود باید یک ID بخصوص داشته باشد، به طور مثال:
<span id="contentsr-1" class="contentsr" ></span>
یعنی هر قسمت خروجی یک ID بخصوص و به این ترتیب قسمت خروجی دوم به صورت زیر:
<span id="contentsr-2" class="contentsr" ></span>
در این شرایط می توانید در سمت کاربر دستورات شرطی یا هر منظور مد نظرتان را اعمال کنید، به فرض:
<script>
$(document).ready(function() {
$('.jens_id').change(function() {
var stateId = $(this).val(); //or this.value
//alert(stateId);
$.post('mojodi_test.php'
,{id:stateId}
,function(data){
if(stateId == 1){
$("#contentsr-1").html(data)
$("#contentsr-2").html('')
} else if(stateId == 2){
$("#contentsr-2").html(data)
$("#contentsr-1").html('')
}
})
})
});
</script>
نکته: فایل jquery.min.js را در ابتدای صفحه قرار دهید یعنی قبل از کدهای داخل تگ script.
هادی
۰۹:۱۰ ۱۳۹۶/۰۴/۱۱
درود
از طریق آجاکس دیتایی را دریافت میکنم و میخوام هرکدام در ردیف خودش باشه ولی در همه ردیف ها آخرین انتخاب را نشان میدهد در صورت امکان راهنمایی کنید.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>
<select name="jens_id[]" class="jens_id" required="">
<option ></option>
<option >1</option>
<option >2</option>
</select><span class="contentsr" ></span>
</td>
</tr>
<tr>
<td>
<select name="jens_id[]" class="jens_id" required="">
<option ></option>
<option >1</option>
<option >2</option>
</select><span class="contentsr" ></span> </td>
</tr>
</table>
<script>
$(document).ready(function() {
$('.jens_id').change(function() {
var stateId = $(this).val(); // or this.value
// alert(stateId);
$.post('mojodi_test.php'
,{id:stateId}
,function(data){
$(".contentsr").html(data)
})
})
});
</script>
در فایل test.php هم که عملا دیتا را بررسی و بازگشت میده
<?php
include 'db/db.php';
if(isset($_POST['id'])){
$id=$_POST['id'];
$sql=$db->query("SELECT * FROM anbar_jens WHERE jens_id='$id'");
while($row=$sql->fetch()){
$mojodiha= ($row['jens_kharid'] - $row['jens_forosh']);

?>
موجودی<?php echo $mojodiha; }?>عدد
<?php } ?>
با توجه به اینکه کد به صورت آنلاین قابل تست نیست نمی توان راهنمایی دقیق کرد، اما به نظر باید قسمت PHP شما در نهایت یک رشته قابل تجزیه خروجی دهد، به طور مثال:
1|2|3|4
و در سمت کاربر موارد را با کلید تجزیه (که در این مثال علامت | می باشد) و به کمک متدهایی مانند split به آرایه تبدیل کنید و هر مقدار را در فیلد خود قرار دهید، در شرایط فعلی کد PHP صرفا یک مقدار را به عنوان پاسخ به مرورگر می دهد و طبیعی است که همان مقدار در همه فیلدها چاپ شود.
sasan
۱۶:۳۲ ۱۳۹۴/۰۴/۰۷
سلام
اگه بخوایم تعداد متغییرها رو افزایش بدیم باید چه کار کرد ؟
اگه بجای select از textbox استفاده بشه بجای onchange چی قرار بدم که با تایپ کردن در فیلد عمل انجام بشه ؟

باتشکر
باید با Syntax دستورات جاوا اسکریپت آشنا باشید و متغیرهای جدید را به صورت نمونه در این قسمت تعریف کنید:
xmlHttp.open("GET", "getlist.php?q=" + str + "&t=" + var, true);
رویداد مناسب برای فیلد متنی onkeyup است، البته در صورت نیاز باید یک تکه کد جاوا اسکریپتی بنویسید که به فرض بعد از 2 ثانیه وقفه در تایپ (یعنی زمانی که کاربر به صورت کامل عبارت را تایپ کرد)، درخواست به سرور ارسال شود.
مجتبی موسوی
۱۳:۵۴ ۱۳۹۳/۰۹/۰۳
سلام ، ممنون بابت این نوشته
چطور میشه یک لیست از آیتم ها رو نشون داد ، بعد برای هر کدوم یک لینک گذاشت ( مثلا "اضافه کردن" )
وقتی روی هر آیتم کلیک میشه اون پایین اضافه بشه
مثل اون چیزی که شما گذاشتید
پاسخ کوتاهی برای سوالتان وجود ندارد! قاعدتا مانند آموزش حاضر نیاز به آشنایی با کدنویسی JavaScript + Ajax است.
امید
۰۲:۳۷ ۱۳۹۳/۰۷/۱۳
سلام
- برای مورد اول باید خروجی اولین بارگذاری را با استفاده از PHP چاپ کنید،
این راه حل جوابگو نمی باشد. مگر این کدها از تکنیک آژاکس استفاده نمی کند؟ پس دومین و ... بارگذاری در کار نخواهد بود.
لطفا اگر ممکن است با تکه کدی راهنمایی نمایید.
با تشکر
زبان های وب در تعامل با یکدیگر هستند و در کنار هم می توانند هدف خاصی را تحقق بخشند، در اینجا منظور از اولین بارگذاری زمانی است که صفحه را (به صورت معمولی و نه Ajax) فراخوانی می کنید، در این مرحله می توانید خروجی را در PHP طوری برنامه نویسی کنید که با حالت انتخاب یک مقدار پیش فرض چاپ شود، زمانی که مقدار اولیه در مرورگر چاپ شد، در درخواست های بعدی از Ajax استفاده می شود، در واقع تئوری شبیه به بخش کدهای کپچا و تعویض آن در سایت های مختلف!
امید
۰۰:۵۰ ۱۳۹۳/۰۷/۰۸
ممنونم بابت پاسخ گویی سریعتان
انتخاب می شود ولی متاسفانه با رفرش چیزی نمایش داده نمی شود و تا زمانی که دستی انتخاب نکنی خروجی مورد نظر نمایش داده نمی شود.
در رابطه با موضوع دوم منظور این هست که در واقع دو تا لیست انتخاب زیر هم می آید و هر کدام از لیست ها مربوط به قسمتی می باشد.
به عنوان مثال ورزشی
لیگ های اروپایی
لیست 1 : (انتخاب لیگ مورد نظر)
1. لیگ برتر انگلیس
2.بوندسلیگای آلمان
3. لوشامپیونه فرانسه
4.لالیگای اسپانیا
5.سری آ ایتالیا
لیست 2: (بازی هایی که هفته به هفته در حال برگزاری است)
هفته 1
هفته 2
.
.
.
هفته n
ممنون
انجام این کارها نیازمند تسلط نسبی و تمرین و تکرار قبلی در زمینه زبان های وب از جمله PHP و JavaScript است، در غیر این صورت توضیحات ما کمکی نخواهد کرد!
- برای مورد اول باید خروجی اولین بارگذاری را با استفاده از PHP چاپ کنید، یعنی خروجی را طوری چاپ کنید که گزینه مورد نظر به حالت انتخاب (selected) و خروجی مربوط به آن در صفحه وجود داشته باشد.
- توضیح شما برای مورد دوم خیلی واضح نبود، تا آنجا که متوجه شدیم برای این کار می توانید با توجه به مقدار انتخاب شده، تگ select را در کدهای PHP سرور متناسب با آن تنظیم کنید، در واقع زمانی که یک گزینه را انتخاب می کنید، با توجه به مقدار انتخاب شده در پاسخ درخواست Ajax یک فیلد select با پارامترهای مربوط به آن (option ها) خروجی دهید تا در مرورگر کاربر نمایش داده شود (باید پاسخ را در مرورگر با جاوا اسکریپ چاپ کنید).
امید
۱۷:۴۶ ۱۳۹۳/۰۷/۰۷
سلام
ممنون از سایت خیلی عالیتون
چطور می توان همین کدها را به گونه ای تغییر داد که اولا لیست بر روی یک مقداری پیش فرض تنظیم شده باشد و بدون هیچ انتخابی اطلاعات قابل مشاهده باشد.
سوال بعد اینکه چطور می توان 2 تا لیست را با هم ادغام کرد؟
برای مورد اول باید هنگام چاپ خروجی اولیه، کدها را با حالت انتخاب شده در قسمت select option چاپ کنید (option مورد نظر پارامتر selected داشته باشد)، در مورد بخش دوم سوال دقیقا متوجه منظور شما از ادغان دو لیست نشدیم!
مرتضی
۱۴:۵۹ ۱۳۹۳/۰۴/۲۶
با تشکر از توضیحاتتون من یه صفحه دارم شامل 4 تکست بکس میخوام تو اولی نام را وارد کنم بعد اطلاعات افراد مشابه را توی جدول بیارم حالا کاربر وقتی روی نام مورد نظر کلیک می کنه بقیه اطلاعات توی 3 تا تکست بکس دیگه وارد بشه این کارا وقتی فقط یک صفحه داشته باشم میشه انجام داد ولی چطور با آژاکس و از طریق 2 صفحه انجام بدم.
منظورتان از صفحه مشخص نیست؟!
اگر منظور این است که در هنگام نمایش نتایج، اگر تعداد افراد زیاد بود، به صورت صفحه به صفحه نمایش داده شود، این کار ساده نیست و توضیح مختصری ندارد، علاوه بر اینکه باید بر CSS برای طراحی رابط کاربری مناسب مسلط باشید، باید بتوانید بین Ajax و PHP یک تعامل برقرار کنید که به فرض Ajax در صفحه اول شماره 1 و تعداد 30 را به PHP بدهد، در صفحه دوم شماره 31 و تعداد 30 و الی آخر که مدیریت این فعل و انفعال نیازمند تسلط بر JavaScript و PHP است.
۲۲:۱۲ ۱۳۹۳/۰۴/۲۰
بله تشکر انجام شد باز هم ممنون ازشما...
۲۱:۵۴ ۱۳۹۳/۰۴/۱۹
در صفحۀ اول باید نوشته شه؟ بعد که نتایج صفحه بعد چاپ شه چه جوری پاک کنیم مطالب صفحه اصلی رو؟!
سوالتان خیلی واضح نیست! اگر منظور حذف مقدار اولیه و جایگزینی با مقداری است که توسط درخواست Ajax دریافت می شود، باید کار با متد document.getElementById و innerHTML (در جاوا اسکریپت) را بلد باشید، به عبارتی مقدار اولیه باید در یک div با id مشخص خروجی داده شود و مقدار جدید جایگزین آن شود.
۲۲:۱۵ ۱۳۹۳/۰۴/۱۸
سلام خیلی خوب بود ممنون
فقط اگر بخوایم همون اول که صفحه باز میشه هم اجرا بشه و خالی نباشه صفحه، باید چی کار کرد؟
می توانید همزمان با بارگذاری صفحه، موارد را با پرس و جوهای MySQL و با استفاده از PHP در خروجی چاپ کنید، در این رابطه باید کار با PHP و MySQL را بلد باشید.
میثم
۰۹:۵۰ ۱۳۹۳/۰۳/۲۵
منظورم از نظر کنسرسیوم جهانیه وبه
برنامه نویسی وب خیلی گسترده است یک سایت خاص رو با چندین نوع مختلف کد میشه نوشت
که البته تو این مورد شما میفرماید شیوه متداوله پس مشکلی نیست
مرسی.
متد split مربوط به استاندارد جاوا اسکریپت است که از این نظر هیچ مشکلی نیست، در رابطه با گستردگی برنامه نویسی وب شاید در نگاه اول اینگونه باشد، چون برای ایجاد یک صفحه وب، معمولا چندین زبان (سمت کاربر و سمت سرور) مختلف باید با هم در تعامل باشند، اما با کسب تجربه در این خصوص، به مرور مشخص می شود که چه ارتباط جالبی بین آنها وجود دارد و در کجا ترجیح با چه شیوه ای است (مهم استفاده از یک شیوه بهینه از میان چندین روش خوب است!)، البته در این حوزه با محدودیت هایی نیز مواجه هستیم که قدرت مانورمان را کمی محدودتر می کند (مانند بحث پشتیبانی مرورگرها، وجود فاصله بین کاربر نهایی و سرور و در نتیجه کاهش سرعت و محدودیت حجم اطلاعات و...).
میثم
۲۳:۴۶ ۱۳۹۳/۰۳/۲۲
سلام
ممنون بابت پاسخ قبلی.
تابع اسپلیت کارم رو راه انداخت و پاسخ رو تبدیل به آرایه ای کرد که خیلی راحت میشه همزمان خروجی های متفاوت رو در مکان های متفاوت چاپ کرد.
فقط سوالی که پیش میاد ، آیا این کار استاندارد هست؟
مرسی.
منظورتان از "استاندارد" مشخص نیست؟!، استفاده از این متد به خودی خود مشکلی ندارد و یک شیوه متداول است که در تمام مروگرها پشتیبانی می شود.
more لطفا پیش از ارسال دیدگاه نکات زیر را مد نظر داشته باشید:
- به سوالات کلی، زمانبر، مبهم و مشکلاتی که تلاشی برای رفع آنها نکرده باشید پاسخ مختصر داده شده یا به بخش برنامه نویسی اختصاصی ارجاع داده می شوند.
- کدها و اسکریپت های طولانی را ترجیحا در یک صفحه وب آنلاین یا به صورت حساب موقت و آزمایشی قرار دهید تا امکان بررسی دقیق مشکل و خطایابی میسر باشد.
- تمام دیدگاه های ارسالی خوانده شده و برای هر کاربر مدت زمان لازم جهت پاسخگویی در نظر گرفته می شود، لطفا از طرح سوالات متعدد در بازه زمانی کوتاه خودداری کنید.



 refresh
10 × 10
7 × 3
20 × 20
=