PHP، SQL Server و زبان فارسی

در هنگام ذخیره و بازیابی عبارت‌های فارسی( یونیکد ) در SQL Server از طریق php با چند مشکل مواجه خواهید شد

مشکل نخست آنکه با استفاده از کتابخانه‌های پیش‌فرض php امکان ذخیره و بازیابی در SQL Server 2008 ممکن نیست
برای حل این مشکل باید فایل زیر را دریافت کنید و در شاخه‌ی php جایگزین کنید
قبل از جایگزین کردن از فایل اصلی پشتیبان تهیه کنید

http://www.helpspot.com/downloads/files/ntwdblib.dll

مشکل دوم آنکه فیلدهای متنی فارسی معمولا با فرمت nvarchar یا ntext ذخیره می‌شوند
و از طرفی رابط انتقال دهنده‌ی عبارت‌ها از php به SQL با فرمت ANSI کار می‌کند

اگر هدف ذخیره‌ی اطلاعات در فیلد nvarchar باشد، تبدیل متن از UTF-8 به UCS-2LE ( یونیکد استاندارد ویندوز ) و سپس تبدیل متن به varbinary مشکل را حل می‌کند:

<?php
	$utf8 = 'متن فارسی';
	$ucs2 = iconv('UTF-8', 'UCS-2LE', $utf8);
	$hex = unpack( 'H*hex', $ucs2 );
	$varbin = "0x{$hex['hex']}";
 
	mssql_query( "INSERT INTO mytable ( nvarcharField ) VALUES ( $varbin )", $link );
?>

و مشکل سوم در هنگام ذخیره‌ی متن در فیلدهایی با فرمت ntext به وجود می‌آید
در این نوع فیلد تبدیل ضمنی از varbinary انجام نمی‌شود و راه حل آن تبدیل صریح با کمک دستورات SQL هست:

<?php
	mssql_query( "INSERT INTO mytable ( ntextField ) VALUES ( CAST( $varbin AS NVARCHAR( 1000 ) )", $link );
?>

برای بازیابی اطلاعات هم می‌توانید از قطعه کد زیر که عکس عملیات بالا است، استفاده کنید:

<?php
	$result = mssql_query( 'SELECT CONVERT( VARBINARY( 1000 ), nvarcharField ) FROM mytable', $link );
 
	while ( ( $row = mssql_fetch_array( $result, MSSQL_BOTH ) ) ){
		echo( iconv( 'UCS-2LE', 'UTF-8', $row[ 'nvarcharField' ] ) );
	} 
?>

این شیوه برای استفاده‌های محدود کاربرد دارد و چنانچه قصد داشته باشید حجم زیادی از اطلاعات را در SQL Server ذخیره و بازیابی کنید بهتر است از افزونه‌ی جدیدی که مایکروسافت برای ارتباط php با SQL Server تهیه کرده استفاده کنید.

این نوشته در PHP, برنامه‌نویسی, پایگاه داده ارسال و , برچسب شده است. افزودن پیوند یکتا به علاقه‌مندی‌ها.

۱۴ دیدگاه برای PHP، SQL Server و زبان فارسی

  1. somayeh می‌گوید:

    با سلام
    بسیار سپاس گذارم از راهنمایی تون خیلی کمکم کرد. موفق باشید

  2. sogand145 می‌گوید:

    سلام ، ممنون از راهنماییتون ، من دارم با همین افزونه جدید کار می کنم، البته تازه دارم ازش استفاده می کنم و میخواستم بدونم که ممکنه به همین مشکل های بالا بر بخورم ؟ اونم با فارسی مشکل داره؟

    • امیرمسعود ایرانی می‌گوید:

      با سلام

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

      • sogand145 می‌گوید:

        ظاهرا با select مشکلی نداره ولی الان یه چند ساعتیه که وقتمو سر insert کردن داده ها گرفته ، واقعا دیگه خستم کرده، خیلی عجیبه! یه جدول درست کردم با فیلد های nvarchar ، ولی نتونستم داده فارسی insert کنم، در عوض فقط داده انگلیسی insert شد. ولی یه جدول دیگه درست کردم که فقط نوع داده int بهش اضافه شده بود و هر کاری کردم نه فارسی کار کرد و نه انگلیسی….;-((((

  3. sogand145 می‌گوید:

    مرسی از راهنماییتون ، راستش باید بگم که اونو هم گذاشتم
    با این دستور :

    <?php
    $pdo->setAttribute( PDO::SQLSRV_ATTR_ENCODING, PDO::SQLSRV_ENCODING_UTF8 );
    ?>

    ولی باز نمی تونه insert انجام بده…:-((((
    فکر می کنم باید به data type ها توجه بیشتری داشته باشم و بدونم که هر کدوم چه نوعی رو ساپورت می کنن…
    از طرفی دارم با PDO کار می کنم و خیلی هم بهش مسلط نیستم ولی خب تا اینجا عین کتاب های راهنما عمل کردم ولی دلیل کار نکردنشو نمی دونم!!!!! لااقل error هم نمیده که بریم دنبال error اش بگردیم….

    • امیرمسعود ایرانی می‌گوید:

      اینجا محل مناسبی برای گفتگو در این مورد نیست
      لطفا از طریق ایمیل کد خودتون رو برایم ارسال کنید تا ببینم آیا می‌توانم اشکال آن را پیدا کنم؟
      amib [at] amib.ir

  4. laleh می‌گوید:

    سلام
    من با استفاده از pdo دستور insert رو نوشتم ولی کار نمی‌کنه می‌شه کمکم کنید مشکلشو پیدا کنم
    کدی که نوشتم رو براتون می‌ذارم
    ….

    • امیرمسعود ایرانی می‌گوید:

      با سلام
      کد شما رو به دلیل بلند بودن حذف کردم
      اشکال‌های زیادی در کد شما وجود داره
      مثلا متغیرهایی که استفاده کردید جایی مقدار دهی نشدند
      به پارامترهایی که برای دستور bindParam هم مشخص می‌کنید بیشتر دقت کنید
      متغیرهایی به این دستور فرستادید که در مقابل دستور prepare تعریف نشدند
      در دستور Insertی هم که نوشتید اسم اولین فیلد NULL است که احتمالا منظورتان id بوده است
      برای استفاده از autoincrement باید مقدارش را NULL بدهید نه اسمش را

  5. laleh می‌گوید:

    ممنون از راهنماییتون

  6. شهرام می‌گوید:

    سلام.
    من هنوز با دستور select مشکل دارم . میشه راهنماییم کنید. به صورت علامت سوال نشون میده

    • امیرمسعود ایرانی می‌گوید:

      با سلام
      لطفا یک قطعه کد حداقلی که اشکال موردنظر را دارد به همراه پشتیبانی پایگاه داده به ایمیل بنده
      amibct در gmail ارسال بفرمایید تا امکان بررسی اشکال فراهم شود
      با سپاس

  7. peyman می‌گوید:

    سلام.هرکاری میکنم نمیشه که به sql server وصل شم.
    همش این خطا رو میده:
    Fatal error: Call to undefined function mssql_connect()
    حتی رفتم فایل های php_pdo_mssql.dll و php_mssql.dll رو دانلود کردم و از اون روش هایی که میگن استفاده کردم،ولی باز درست نشد.

    حتی بجاش رفتم فایل های php_sqlsrv_54_ts.dll و php_pdo_sqlsrv_54_ts.dll رو دانلود کردم(ورژن php من،۵/۴ هستش)،که تا بتونم بجای کدهای mssql از کدهای sqlsrv استفاده کنم،ولی اصلا sqlsrv وارد محتوای php من نمیشه که ازش استفاده کنم.
    دیگه واقعا موندم که باید چیکار کنم.
    آخه استادمون گفته باید پایگاهتون فقط sql server باشه،نه my sql یا هر پایگاه دیگه ای
    خواهش میکنم بهم بگید باید چیکار کنم؟

پاسخ دهید

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

شما می‌توانید از این دستورات HTML استفاده کنید: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>