گیک فارسی

نوشته های یک گیک فارسی از فعالیت ها ،‌ علاقه مندی ها و نقد هایش

اتصال و استفاده از پایگاه داده MSSQL در PHP

24 دیدگاه‌ها

به نظرم خیلی اشتباهه که وقتی با PHP کار میکنیم کلاً از ویندوز و IIS استفاده کنیم که حالا اصلاً بحث استفاده از MSSQL هم مطرح بشه. ولی نمیشه زیاد گلایه کرد و خیلی‌ها هم هستند که با سرویس دهنده های ویندوزی به خاطر آشنایی بیشتر ، راحت‌تر هستند و ترجیح هم میدهند از MSSQL استفاده کنند. ولی قبل از خوندن این مطلب به شدت توصیه میکنم که تجدید نظر کنند و از MySQL یا Maria DB یا Postgre SQL استفاده کنند.

به طور کلی چندین روش برای اتصال به MSSQL وجود داره که من 5 روش معمول را میگم و یکی را که توصیه میکنم توضیحات و کدش را میگذارم.

روش اول : تا نسخه 5.3 خود php یک Extension به نام mssql داشت که هنوز مستنداتش هم توی سایت php.net موجوده ولی دیگه پشتیبانی نمیشه ، حالا اگه خیلی علاقه دارین میتونید از نسخه های قدیمی تر php استفاده کنید و از این extension استفاده کنید. البته قرار نیست مثلا همه امکانات SQL 2012 را هم پشتیبانی کنه و ممکنه خیلی bug داشته باشه. مستنداتش هم اینجاست.

روش دوم : مایکروسافت مثل اینکه خودش متوجه شده اگه دست به کار نشه توی php واقعا کسی با مشکلات driver های فعلی سراغ mssql نمیره و خلاصه آستین ها را بالا زدند یا سفارشش را دادند. خودش اومده یک extension برای php درست کرده که به نسخه 3 هم رسیده و اینطور که پیداست خیلی امکانات خوبی داره و mssql را به خوبی پشتیبانی میکنه. مشکلش اینه که فقط روی windows قابل استفاده هست و برای لینوکس تا زمان نوشتن این مطلب وجود نداره. این سایتش و همه اطلاعات مربوطه برای علاقه مندان.

توجه : سه روش بعدی در مورد PDO هست.

روش سوم : یکی از Driver های PDO اسمش PDO_DBLIB هست که امکان اتصال و استفاده از MSSQL و Sybase را از طریق کتابخونه FreeTDS فراهم میکنه. این Extension از نسخه 5.3 PHP به بعد برای ویندوز پشتیبانی نمیشه (وجود نداره) و فقط روی لینوکس قابل استفاده هستش. نکنه اینکه DB-LIB قدیمیه ، Thread un-safe هست و هزار مشکل دیگه که در زمان کار کردن بهش بر میخورین.

روش چهارم : یکی دیگه از driver های PDO اسمش PDO_SQLSRV هستش که شما باید همون extension که توی روش دوم اشاره کردم را بگیرید و با توجه به non thread safe یا thread safe بودن نسخه php با کپی کردن dll های مربوطه و اعمال تغییرات توی php.ini اون را نصب کنید. نکته اینکه فقط روی ویندوز هم جواب میده. اینجا طریقه نصب را بهتر توضیح داده.

روش پنجم : این روش که هم روی ویندوز و هم روی لینوکس جواب میده (بدیهی هست که باید ODBC روی سیستم عامل نصب باشه به همراه Extension مربوطه) از طریق PDO_ODBC هستش.

بهتره از Driver های جدید مایکروسافت استفاده کنید که خیلی قابلیت داره و برای هر دو سیستم عامل هم طراحی شده. از اینجا نسخه ویندوزی را بگیرین و از اینجا نسخه لینوکسی را.

و اما کد :

try{
  $hostname = "host,port";
  $dbname = "database_name";
  $username = "username";
  $pw = "password";
       
  $pdo = new PDO ("odbc:Driver={SQL Server};Server=$hostname;Database=$dbname; Uid=$username;Pwd=$pw;");
       
} catch (PDOException $e) {
  echo "Failed : " . $e->getMessage() . "\n";
  exit;
}
 
$query = $pdo->prepare("select field_name from table");
$query->execute();
 
for($i=0; $row = $query->fetch(); $i++){
  echo ($i + 1)." - ".$row['field_name']."";
}

نکته مهم : یکی از مشکلات اصلی دوستان درست set نکردن hostname$ هستش. متوجه باشین دادن ip یا ادرس FQDN (مثل mssql.mydomain.com) ممکنه خطای timeout بده. اونجاست که شما باید به دو نکته توجه کنید.پورت پیش فرض 1443 هست اما اگه شما چند تا instance داشته باشین اونوقت پورت ها به صورت رندوم اختصاص داده میشه و باید توی host$ از instance name استفاده کنید یا پورت بدین ، اینطوری :

$hostname = "{IP ADDRESS},6688"; // port version
$hostname = "{IP ADDRESS}\SQLEXPRESS"; // instance version

پس حتما از مسئول هاست بپرسین تنظیماتشون چیه و اگه خودتون نصب میکنید از instance name استفاده کنید. (توی SQL server Configuration Manager هست).



برچسب‌ها:

  1. زهره گفت:

    عااااااالی بود ، کلی دنبالش گشته بودم . مرسی 🙂

  2. مصطفی گفت:

    سلام
    من متصل شدم اما داده های فارسی رو بصورت علامت سوال (؟؟؟؟) نشون میده 🙁

    1. یونیک مدیر گفت:

      بعید میدونم ، خروجی را UTF-8 نشون میدی دیگه ؟
      اطمینان داری محتوای پایگاه داده فارسی و UTF-8 هست ؟

    2. رضا گفت:

      سلام
      من هم وقتي وصل شدم ديدم كه كاراكتر هاي فارسي ؟ نشون مي ده اما مشكلو حل كردم:
      راه حل:
      شما بايد از كد زير براي تبديل encoding به utf-8 استفاده كني
      iconv(“CP1256″,”UTF-8”, $row)
      لطفا دقت كنيد به خاطر راست چين بودن متن پرانتز اشتباهي اين طرف افتاده پرانتز اول بايد بره آخر!!!!
      اين فرمول مي ياد متغير row$ كه همون خروجي ما از sql server است را به از cp1256 به utf-8 تبديل مي كنه.
      اگه ديدي باز هم نشد به جاي استفاده از
      Driver={SQL Server}
      (در روش پنجم از روش هايي كه در بالا گفته شده ) از اين كد
      Driver={SQL Server Native Client 10.0}
      استفاده كنيد و بعد چك كنيد اگر باز هم نشد
      نوبت كد زير:
      اين يكي كمك مي كنه تا بين كدينگ هاي مختلف جست و جو و بهترين كدينگ را پيدا كني:

      for($i=0; $row = $query->fetch(); $i++){
      $tab = array(“UTF-8”, “ASCII”, “Windows-1252”, “ISO-8859-15”, “ISO-8859-1”, “ISO-8859-6”, “CP1256”);
      $chain = “”;
      foreach ($tab as $i)
      {
      foreach ($tab as $j)
      {
      $chain .= ” $i$j “.iconv($i, $j, $row[‘course_name’]);
      }
      }
      echo $chain;
      }

      از بين نتايج ببينيد كدوم يكي فارسي رو درست نشون مي ده همون كد نشانه كدينگ صحيحه.
      متشكرم

      1. یونیک مدیر گفت:

        البته مشکل اصلی شما اینه که مقادیری که توی MS SQL ریختین پونیکد نبوده و WINDOWS-1256 با همون عربی بوده. برای تبدیل هم iconv روش خوبیه اما اگه من جای شما بودم یکبار کل پایگاه را تبدیل میکردم و خلاص. مگه اینکه این پایگاه از طریق یک برنامه دیگه ای به روز میشه که اطلاعات را داره عربی ذخیره میکنه. (منظورم از عربی کدپیج ۱۲۵۶ روی ویندوز هست که عربی هستش)

  3. mojtaba گفت:

    سلام
    من از روش مر حله اخری که شما گفتید استفاده کردم.
    تمامه کار ها رو هم انجام دادم.
    php 5.1 – sqlserver2014
    ولی خطای زیر رو نشون میده
    Warning: mssql_select_db() [function.mssql-select-db]: message: The USE database statement failed because the database collation Persian_100_CI_AI is not recognized by older client drivers. Try upgrading the client operating system or applying a service update to the database client software, or use a different collation. See SQL Server Books Online for more information on changing collations. (severity 16) in /var/www/html/crmgaz/q.php on line 16

    Warning: mssql_select_db() [function.mssql-select-db]: Unable to select database: GasAVL in /var/www/html/crmgaz/q.php on line 16

    1. یونیک مدیر گفت:

      سلام

      خیلی سر راست داره توضیح میده که !
      میگه سیستم عاملت database collation را به خاطر قدیمی بودن driver های سیستم عاملت نمیشناسه.
      شما چند تا کار انجام بده :؛
      ۱ – نگفتی سیستم عاملت چیه اما سعی کن بری روی Windows 8 حداقل اگرچه دوستانی که ویندوز کار میکنند میگن نسخه ۱۰ خیلی بهتره !
      ۲ – من نسخه ۱۱ را توی این پست لینک دادم در حالی که نسخه ۱۳ هم اومده و میتونی از اینجا بگیری
      ۳ – توی این تاپیک انجمن یک نفر با یک تغییر کوچیک تونسته مشکل را حل کنه که بهتره امتحان کنی

      من دارم با یک ماه تاخیر جواب میدم و عذر خواهی میکنم.

  4. رضا گفت:

    سلام و تشکر از زحمت شما
    اگر امکان دارد راهنمایی فرمایید:
    من می خواهم php که در یک سرور دیگر با wamp کار می کند را به sql server در یک سرور دیگر وصل کنم حالا:
    1-نرم افزار odbc بر روی کدوم سرور باید نصب شود؟
    2- منظور از فرمایش شما ( به همراه extension های مربوطه) کدام است؟
    متشکرم

    1. یونیک مدیر گفت:

      ۱ – روی سروی که wamp‌ داره.
      2 – منظورم اینه اگه با PDO یا ODBC Unified که از کتابخونه ها یا Extension های PHP هستند استفاده میکنید. اون ها هم باید نصب باشن.

  5. رضا گفت:

    سلام و متشکرم از این همه لطف شما استاد گرانقدر
    باز هم شرمنده سوالی دارم:
    من به دیتابیس sql server 2008 r2 وصل شدم موفق هم شدم اما فارسی ها علامت سوال می یاد.
    دنبال راه حل گشتم پیدا هم کردم :
    iconv(“ISO-8859-6”, “UTF-8”, $row)
    row$ همون خروجیه که تبدیل به utf-8 میشه و نشون می ده ولی مشکل اینه که این روش رو روی sql server 2014 تست کردم درست کار کرد ولی روی Sql server 2008 r2 تست می کنم هنوز هم علامت سوال نشون می ده.
    میشه بفرمایید کدینگ مربوط به Sql server 2008 r2 چیه که من داخل این کد جای ISO-8859-6 قرار بدم تا فارسی رو درست نشان بده؟

    واقعا ممنونم بابت پاسخگوییتون
    امیدوارم روز به روز موفق تر باشید

    1. یونیک مدیر گفت:

      راستش encoding اطلاعات شما ربطی به نسخه mssql server نباید داشته باشه. اینی که میگین عجیبه و فکر کنم مشکل از تفسیر خودتون باشه.

  6. مهدی گفت:

    Failed : SQLSTATE[IM002] SQLDriverConnect: 0 [unixODBC][Driver Manager]Data source name not found, and no default driver specified

    سلام این ارور رو روی انلاین میده. مشکل از چیه؟

    1. یونیک مدیر گفت:

      خطای خیلی کلی هست !
      از ODBC استفاده میکنی توی لینوکس ؟ میتونی از نرم افزار دیگه ای به همین database وصل بشی ؟

  7. کورش گفت:

    عرض سلام و خسته نباشید
    من از این کد iconv(“CP1256″,”UTF-8”, $row) استفاده کردم و جواب داد.

    موفق و پیروز باشید.

  8. رضا جوان معقول گفت:

    سلام. من از روش چهارم استفاده کردم مشکلی هم نداشتم خداروشکر

    من یک برنامه نوشتم که به MSSQL SERVER که در یک سرور بر روی بستر اینترنت هست بهش متصل میشم. البته به وسیله زمپ. حتی دیتا دریافت میکنم.

    حالا وقتی همین کد رو میبرم توی سی پنل میخوام اجرا کنم ارور زیر رو میده
    pdo_sqlsrv و sqlsrv رو در قسمت تنظیمات PHP تیکش رو فعال کردم

    ارتباط با دیتابیس را بررسی کنید.
    Array ( [0] => Array ( [0] => IMSSP [SQLSTATE] => IMSSP [1] => -49 [code] => -49 [2] => This extension requires the Microsoft ODBC Driver for SQL Server. Access the following URL to download the ODBC Driver for SQL Server for x64: https://go.microsoft.com/fwlink/?LinkId=163712 [message] => This extension requires the Microsoft ODBC Driver for SQL Server. Access the following URL to download the ODBC Driver for SQL Server for x64: https://go.microsoft.com/fwlink/?LinkId=163712 ) )

    1. یونیک مدیر گفت:

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

  9. یاور گفت:

    سلام و سپاس
    سوالی داشتم و اون اینکه برای اتصال اسکریپت php که روی یه هاست سی پنل هست به دیتابیس ویندوزی SQL سرور در یک سرور دیگه چه روشی باید انجام بشه؟
    در اصل اینو نفهمیدم که آیا تو سرور دیتابیس ویندوزی هم باید درایوری چیزی نصب بشه یا نه؟

    1. یونیک مدیر گفت:

      خیر روی سیستم ویندوزی نیازی نیست چیزی نب بشه و فقط باید امکان Remote و Port روی اون سرور برای خارج از اون مهیا باشه.

      1. یاور گفت:

        سپاس
        آیا براتون مقدور هست که (با دریافت هزینه اینکار) کد اتصال php به سرور ویندوزی دیتابیس با مشخصاتی که از طریق واتساپ یا تلگرام میدم خدمتتون برام بفرستید که فقط بتونم از هاست لینوکس به دیتابیس ویندوزی وصل بشم ؟

        [بخش حذف شذه توسط مدیر]

      2. یونیک مدیر گفت:

        نیاز به نوشتن کد خاصی نیست ، کدی که توی مطلب بالا هست به خوبی کار میکنه. هاست لینوکسی شما اگه Shared باشه امکان داره به شکلی کانفیگ شده باشه که شما نتونید روی سرویس دهنده MSSQL خارجی وصل بشین. روی سرویس دهنده Shared باید از پشتیبانی بپرسین ODBC روی PDO قابل استفاده باشه و نسخه MSSQL ODBC هم نصب باشه و همینطور PORT خروجی برای MSSQL Server هم باز باشه تا بتونید وصل بشین. اگه هم سرویس دهنده اختصاصی دارین خودتون باید همه این موارد را نصب و پیکربندی کنید. کدی که توی پست هست در حالت نصب بودن همه موارد مذکور باید کار کنه! اگه خطایی که میگیرین را بدونم چیه میتونم بیشتر راهنمایی کنم.

  10. مهدی گفت:

    سلام مهندس جان ممنون از مطلب بسیار کاربردیتون.
    من هم مشکل همین دوستمون رو دارم. از هاست شیر استفاده میکنم.
    البته درایورها رو از سی پنل نصب کردم اما موقع اجرای قطعه کد php به خطای زیر میرسم:

    Failed : SQLSTATE[01000] SQLDriverConnect: 0 [unixODBC][Driver Manager]Can’t open lib ‘SQL Server’ : file not found

    1. یونیک مدیر گفت:

      سلام ، روی سرویس های Shared هم من تونستم ارتباط برقرار کنم اما با همکاری پشتیبانی ، این خطایی که شما میگیری به احتمال زیاد به تنظیمات ODBC برای SQL Server بر میگرده و باید با پشتیبانی مطرح کنید به نظرم.

  11. کمال گفت:

    سلام.
    Failed : could not find driver
    این خطا رو میده
    فایل های مربوط به php ورژن 7.4 x64 رو
    php_pdo_sqlsrv_74_nts_x64.dll
    , php_pdo_sqlsrv_74_ts_x64.dll
    و داخل پوشه ext گذاشتم
    و به php.ini هم اضافه کردم
    extension=pdo_sqlsrv_74_nts_x64
    extension=pdo_sqlsrv_74_ts_x64
    کجای کارم ایراد داره؟؟؟
    msodbcsql.msi رو هم نصب کردم

    1. یونیک مدیر گفت:

      خطا داره میگه که driver را پیدا نمیکنه!
      شما چرا هم nts و هم ts را با هم فعال میکنید !؟ بسته به اینکه php را ts یا nts نصب کردین باید عمل کنین.

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

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