فوت کوزه گری!
اسفند ۱۳م, ۱۳۸۸
گاهی یک فوت کوزه گری رو دونستن میتونه کلی بدادت برسه و از کلی دردسر نجاتت بده! یه قابلیت که توی فایلهای PHP هست اینه که اگه فایل PHP شما قرار نیست که ادامه داشته باشه یعنی قرار نیست بعد از اینکه کد تموم شد،ادامه فایل به صورت HTML باشه، اونوقت میتونید از گذاشتن علامت ?> در انتهای کد خودداری کنید. راستشو بخواید اول که این قابلیت رو دیدم کلا نفهمیدم به چه دردی میخوره یا اگه بیشتر راستشو بخواید به خودم گفتم این قابلیت اصلا احمقانه و به درد نخوره (نتیجه اخلاقی این پست اینه که زود قضاوت نکنید! ) ولی امشب فهمیدم که نخیر! اینطورا هم نیست!
قضیه اینطوریه که یه کدی دارم مینویسم که قراره یه تصویر رو از یه فایل بخونه و به خروجی بده (تابع readfile() از اون توابعیه که بعضیا کمتر میشناسنش!!) همه چی درست بود (البته در ظاهر) اما فایرفاکس خروجی رو نشون نمیداد. نتیجه رو که بررسی میکردم متوجه شدم که Content-Type هم درست ارسال میشه، ولی نمایش داده نمیشه. بارها و بارها کد رو بررسی کردم و هرچه بیشتر چک کردم کمتر نتیجه گرفتم.
تا بالاخره خروجی رو با یه ویرایشگر باینری (HexEditor ) چک کردم. نتیجه دو تا کاراکتر Space در ابتدای فایل تصویر بود. صفحات دیگه رو هم چک کردم. اونجا ها هم این دو تا کاراکتر اضافه بود، ولی خوب html مشکلی نداره با این فااصله های اضافی. فایلهای include شده رو یکی یکی بررسی کردم و آخر سر هم خرابکار، پروژه jDate خودم بود. توی یکی از فایلها بعد از پایان کد و تگ پایان PHP (یا همون ?> ) دو تا فاصله خورده بود. این فایل بعد از آغاز session و ارسال header ها استفاده شده بود و به همین دلیل مشکل خودشو توی اونها نشون نداده بود. جالبتر اینکه یه فایل دیگه هم پیدا کردم که دقیقا این مشکل رو داشت و یه Enter اضافه داشت، که خیلی پیش میاد تو یه ویرایشگر این اتفاق بیفته. تو همه فایلهای دوره ویندوزم هم این مشکل کم و بیش بود :) نتیجه گیری اینکه من از این به بعد کل فایلهایی که با کد PHP تموم میشن رو وقتی بنویسم، خصوصا فایلهایی که قرار نیست خروجی داشته باشن مثل همین کتابخونه ها، به همین صورت و بدون بستن کد PHP مینویسم، توصیه میکنم شما هم همین کارو بکنید. به دردسرش نمیرزه،این یه دفعه دقیقا ۴۵ دقیقه وقتمو گرفت!!
نکته دوم هم اینکه این پست اولین پست من با عینکه! دو سه روز پیش عینکی شدم!! :)
PHP و توابعی که کمتر استفاده میکنیم
اسفند ۵م, ۱۳۸۸
چند تا تابع هست که ممکنه شما ندیده باشیدشون. منم یه چند تایی رو میشناختم که هر کدوم یه وقتایی نجاتم داده بودن از کلی کد نویسی زاید. این شد که تصمیم گرفتم یه چند تایی رو معرفی کنم:
pack()
این تابع یک بار منو نجات داد. PHP برای عملیات بیتی مخصوصا روی فایلها کار چندانی انجام نداده. یعنی تمام توابع برخلاف زبانهای دیگه هستند. مثلا تابع fwrite یه رشته (string )رو توی فایل مینویسه و این یعنی یه مشکل :).
یه زمانی میخواستم برنامه ای بنویسم که یه فایلی ایجاد کنه که توی دلفی بخونمش،اونجا قضیه برعکسه. توی دلفی باینری یه انتخاب ساده تره. اینجا بود که تابع pack رو پیدا کردم این تابع برای ایجاد یک رشته باینری استفاده میشه. یعنی اگه این رشته رو توی یه فایل بنویسی خیلی راحت میتونی مثلا توی دلفی یا سی اونو از فایل بخونی. مثلا برای ایجاد کردن یه خط حاوی دو تا کاراکتر،یه int اینجوری میشه عمل کرد :
خواندن ادامه این مطلب »
MySQL , Menu قسمت دوم
بهمن ۲۵م, ۱۳۸۸
قبل از شروع بگم اصل این ایده رو یکی از دوستام داد، اونم از وب خونده بود. منتها من هیچ چیز مدوّنی از این مطلب نتونستم پیدا کنم هنوز (نگشتم اگه راستشو بخواید) خواستم پیشاپیش بگم، چون حقیقتا به این مساله اهمیت میدم، احترام به حق دیگران.
توی پست قبل، روشی رو بررسی کردم که توی اون روش، از یه سری کوئری ساده استفاده میشد که یه جور منو از دیتابیس بارگذاری بشه (منظور نمایش نیست، فقط بارگذاری منو از دیتابیس به آرایه ، از MySQL به PHP ) ولی مشکل اساسی این بود که توی اون روش، زیادی قابلیت انعطافی وجود نداشت، درجه ها هم نمیشد از یه حدی بیشتر باشه و برای درجه های بالاتر باید کوئری تغییر میکرد که اینکار مستلزم زمان و کد بیشتره.
اما این دفعه روش طور دیگه ای هست. به جای روش قبلی، منو رو به این صورت در نظر بگیرید. (چیزی تغییر نکرده، فقط طرز نمایش عوض شده و به جای یه نمودار، یه سری آیتم تو در تو وجود داره)
جدولی که این دفعه قراره ساخته بشه، ساختار یه کم متفاوتی داره، به این صورت :
CREATE TABLE IF NOT EXISTS `adv_menu` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(60) NOT NULL, `data` varchar(255) NOT NULL, `lside` int(11) NOT NULL, `rside` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM; INSERT INTO `adv_menu` (`id`, `name`, `data`, `lside`, `rside`) VALUES (1, 'Root', 'Root Data', 1, 24), (2, 'Home', 'Home Data', 2, 3), (3, 'Pages', 'Pages Data', 4, 13), (4, 'Articles', 'Articles Data', 14, 23), (5, 'PHP', 'PHP Data', 5, 10), (6, 'Delphi', 'Delphi Data', 11, 12), (7, 'SQL', 'SQL Data', 15, 16), (8, 'Ajax', 'Ajax Data', 17, 22), (9, 'Part2', 'Part2 Data', 18, 19), (10, 'Part1', 'Part1 Data', 20, 21), (11, 'OS', 'OS Data', 6, 7), (12, 'GTrans', 'GTrans Data', 8, 9);
Menu، MySQL و کلا هر چی با M شروع میشه
بهمن ۲۳م, ۱۳۸۸
اولین بار،برای ایجاد کردن یک منوی تو در تو، از یک روش ساده استفاده کردم. روشی که خیلی های دیگر هم از آن مطمئنا استفاده میکنند. (باز هم خیلی بی مقدمه شروع کردم !)
منظورم از منوهای تو در تو خیلی سادست، منوهای کناری سایتها. مثلا یه چیزی مثل شکل زیر:
با این فرض که این منوها قراره از دیتابیس خونده بشن (تو این مورد mysql) و نمایش داده بشن. دیشب یه دوستی هم همین رو پرسید ازم که من اگه باشم چیکار میکنم، و بعد من یه راهی به ذهنم رسید که تا همین الان هم یه کله دارم روش کار میکنم.(البته بگم که یه دوست دیگه هم این ایده رو بهم داد و قرار شد لینکی که اصل ایده از اونجا بوده رو برام بفرسته، ولی این دوست من خیلی بد قوله!!) اول از همه روش قدیمی مو میگم و بعد روش جدیدمو . یعنی قسمت اول روشیه که تا به امروز استفاده میکردم و قسمت دوم روش جدیدیه که مد نظرمه،احتمالا اینو تو دو تا پست سرو سامون بدم تا شاید اون لینکی که دوستم گفت رو تا اون موقع پیدا کردم چون من الان فقط طرح کلیشو میدونم و بقیش کار خودمه و شاید اون بهتر بود.
فرض کنید همون شکلی که بالا هست رو میخوام پیاده کنم. جدولی با یه ساختار ساده ایجاد میکنم :
CREATE TABLE IF NOT EXISTS `simple_menu` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(60) NOT NULL, `parent` int(11) NOT NULL, `data` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM;
این روش،خیلی ساده میتونه برای منوهای تو در توی محدود استفاده بشه. مثلا تا ۴ درجه.(مثل همین تصویر اگر که ریشه رو هم یک درجه حساب کنید)و البته قسمت دیتا هم اصلا استفاده ای توی مثال من نداره و مثلا میتونه لینکی باشه که این منو قراره به اون ما رو هدایت بکنه یا یه چیزی شبیه این. تو این مثال، ما زیاد اونو جدی نمیگیریم :)
مثلا برای این تصویر اطلاعات مورد نیاز من خواهد بود :
INSERT INTO `simple_menu` (`id`, `name`, `parent`, `data`) VALUES (1, 'Root', 0, 'Root Data'), (2, 'Home', 1, 'Home Data'), (3, 'Pages', 1, 'Pages Data'), (4, 'Articles', 1, 'Articles Data'), (5, 'PHP', 3, 'PHP Data'), (6, 'Delphi', 3, 'Delphi Data'), (7, 'SQL', 4, 'SQL Data'), (8, 'Ajax', 4, 'Ajax Data'), (9, 'OS', 5, 'OS Data'), (10, 'GTrans', 5, 'GTrans Data'), (11, 'Part1', 8, 'Part1 Data'), (12, 'Part2', 8, 'Part2 Data');
مترجم گوگل
دی ۲۸م, ۱۳۸۸
همون طور که مطمئنا میدونید مترجم گوگل یکی از ابزارهای قدرتمندیه که توی وب خیلی میتونه کاربردی باشه و کمک کنه. اگه بخواید از این مترجم توی طرف کلاینت استفاده کنید مثلا با کمک جاوا اسکریپت، تقریبا هیچ کاری نداره، چون گوگل API اونو در اختیارتون گذاشته و با افزودن یه سری کد جاوااسکریپت به کد صفحتون، همه چی در اختیار شماست.
اما اگه بخواید از این کد برای طرف سرور استفاده کنید مثلا برای PHP مشکلاتی پیش میاد. چند تا کلاس توی PHPClasses پیدا کردم واسه این کار ولی همه یه روش نسبتا بد داشتن، صفحه مربوط به گوگل رو میخوندن، درخواستو میفرستادن و بعد هم در نهایت صفحه بازگشتی رو بررسی میکردن برای جواب که اصولا روش خیلی بدیه! اگه گوگل یه تغییری تو صفحه بده (که داد) دیگه اون کدها کار نمیکنن.
این شد که نشستم و یه کد واسه این کار نوشتم، یه کد که خیلی ساده به وب سرویس اصلی درخواست رو ارسال میکنه و پاسخ رو که json هم هست، رو به آرایه تبدیل میکنه و در اختیار قرار میده.
این کلاس برای ارسال درخواست از CURL استفاده میکنه اما در صورت در دسترس نبودن از Snoopy استفاده میکنه. قابلیت شناسایی زبان هم وجود داره که میتونه در مواردی مفید باشه.
این کلاس بالاخره امروز تایید شد و در این آدرس قرار گرفت.
البته دموی این کد رو هم میتونید اینجا ببینید.
به روز رسانی : بلافاصله بعد از انتشار کلاس، یک نفر خبر داد که این کلاس با نسخه جدید مترجم گوگل کاملا سازگار نیست، این شد که نشستم و این کلاس رو برای نسخه جدید مترجم هم آپدیت کردم.

