PDA

View Full Version : بخطر افتادن portabality برنامه با استفاده کردن از بسته های pear



arash_hemmat
جمعه 11 فروردین 1385, 13:33 عصر
سلام
برنامه ای نوشتم که توش از یکی دوتا از بسته های pear استفاده کردم ولی در اجرای این برنامه روی سیستمهای مختلف مشکل دارم. اول فرض کردم که pear روی سیستم نصبه و فایلهای بسته رو include نکردم ولی وقتی کد رو روی یک سیستم که روش pear نصب نبود امتحان کردم همونطور که انتظار داشتم کد اجرا نشد. بعد تصمیم گرفتم که بسته هایی رو که تو برنامه ازشون استفاده میکن رو توی برنامه include کنم که با اینکار هم روی سیستمی که pear روش نصب هست به این error برخوردم:

Fatal error: Cannot redeclare class config in ...\php\pear\Config.php on line 0
با توجه به اینکه نمیدونم روی سیستمی که این کد اجرا خواهد شد pear نصب هست یا نه نمیتونم از هیچ کدوم از این روشها استفاده کنم! روشی هم وجود داره که اول کنترل کنم ببینم که pear نصب شده یا نه و بعد تصمیم بگیرم که بسته رو include بکنم یا نه که این روش هم بنظرم روش مناسبی نیست. اگر روش دیگه ای سراغ دارید لطفا من رو بی نصیب نذارید.
(تا جایی که میدونم بعد از php4.3.x یک سری بسته های pear بصورت default نصب میشه و البته همه بسته ها نصب نمیشن.)

oxygenws
جمعه 11 فروردین 1385, 20:56 عصر
یک زمانی با یکی از توسعه دهندگان PHP صحبت می کردم، گفت "با کمک pear می تونی به هدفت برسی" گفتم "به نظرم استفاده از pear خیلی مسخره و به درد نخوره" گفت "آره، درست می گی، اما در برخی موارد و برای برخی افراد می تونه کاربرد داشته باشه"
من می دونستم چی دارم میگم و اون هم منظور من رو می فهمید. به هر کس هم می گم استفاده کردن از pear شرایط خاصی می خواد، طرف بهم می خنده و با غرور میگه، نه، مشکلی نیست!!

موفق باشی.

ramram
جمعه 11 فروردین 1385, 22:39 عصر
منظور امید فکر کنم که من باشم هنوز معتقدم کار pear خوب و پروژه موفقی هست اما پاسخ اون دوستمون که با زیر سوال بردن پروژه pear از طرف امید روبرو شد
این اتفاق اصلا چیز مهم و لاینحلی نیست که شما به این راحتی pear رو زیر سوال می برین اولا که با توابع
()get_required_files(), get_included_files
میتونین در آرایه ای فایلهای اینکلود شده رو داشته باشی خارج از این موضوع کافیست به جایrequire و یا include از require_on,include_once استفاده کنین حالا چیزی به این کوچیکی واقعا portabality رو از نظر شما به خطر میندازه من که فکر نمی کنم شما چطور

oxygenws
شنبه 12 فروردین 1385, 01:10 صبح
منظور امید فکر کنم که من باشم هنوز معتقدم کار pear خوب و پروژه موفقی هست اما پاسخ اون دوستمون که با زیر سوال بردن پروژه pear از طرف امید روبرو شد
خوب فهمیدی :) البته شما تنها برنامه نویس نبودی و نخواهی بود :)

arash_hemmat
شنبه 12 فروردین 1385, 02:17 صبح
با توابع () get_required_files(), get_included_files
میتونین در آرایه ای فایلهای اینکلود شده رو داشته باشی
خیلی ممنون برام عجیبه که توابعی به این سودمندی رو تابحال ندیده بودم!
خیلی سریع راه حلی رو که شما پیشنهاد کرده بودید رو به بوته آزمایش گذاشتم و حاصل کار این کد بود:

<?php
// include PEAR Config
require_once ('Config.php');
// function to check if a pear package is included
// returns true when package is included
function checkPearPackage($package_name)
{
// get the list of included files
$included_files=get_included_files();
// check if the package is included
foreach($included_files as $file)
{
if( eregi('Config.php',$file) )
return true;
}
return false;
}

// if Config is not included include it
if( !checkPearPackage('Config.php') )
{
require_once(pear/PEAR.php);
require_once(pear/Config.php);
echo 'The package is not included and it should be included manually.<br>';

}
else
echo 'The package is included and there is no need to include it.<br>';

// test if Config package is working
$temp=array(
admin_name => 'admin',
admin_email => 'some_email_address'
);
$test = new Config();
$root =& $test->parseConfig($temp, "PHPArray");
$test->writeConfig('test_conf.php','PHPArray');

include('test_conf.php');
echo $conf['admin_name'];
// if the Config package works it should display "admin"

?>
خوب فکر کنم این دقیقا راه حلی بود که شما پیشنهاد کردین و روی سیستمی که pear روش نصب بود بدون مشکل کار کرد ولی روی سیستمی که pear روش نصب نبود حدس بزنید چه اتفاقی افتاد؟! این error رو داد:

Warning: main(Config.php): failed to open stream: No such file or directory in ....public_html/pear_test/index.php on line 3
یعنی کدی که نوشتم بدرد نمیخوره!
(برای اینکه خودتون هم امتحان کنید فایلش رو هم اینجا میزارم)


به نظرم استفاده از pear خیلی مسخره و به درد نخوره
با اینکه pear خیلی اذیتم کرده و فکر کنم که دیگه ازش استفاده نکنم ولی اگر شرایطی پیش بیاد که بشه ازون روی هر سیستمی استفاده کرد بنظر من میتونه خیلی مفید باشه(هرچند که من میدونم به نظر امید هیچی جای بسته های PECL رو نمیده!) برای مثال من به یک کلاس مدیریت فایل config احتیاج دارم و چون نتونستم از بسته pear Config استفاده کنم رفتم و یه کلاس توی سایت http://phpclasess.org پیدا کردم و ازون تو برنامه استفاده کردم ولی همه میدونن که استفاده از همچین کلاسهایی چه ریسکی رو بهمراه داره! بنظر شما باید چیکار کرد؟

arash_hemmat
شنبه 12 فروردین 1385, 02:18 صبح
خارج از این موضوع کافیست به جایrequire و یا include از require_on,include_once استفاده کنین
قبلا امتحان کردم و جواب نداد!

ramram
شنبه 12 فروردین 1385, 09:01 صبح
دوست عزیز وقتی قرار شد که از require_on,include_once دقت کن که دیگه هدف تو باز کردن کلاسهای نصب شده بر روی سرور نیست تو باید آدرس دقیق اون فایلها در اینجا مثلا Config.php رو بدی فراموش نکن آدرس دقیق
دوما آخه کلاسهای پیر چه استفاده بشن چه نه برای من نفع یا ضرری نداره مسئله اینجاست که این ایراد از اون نیست از نحوه استفاده توسط شما برای همین من این تاکید رو دارم به هر شکل شما از چیز که دوست دارید می تونین استفاده کنین اما می خوام این رو هم بدونین که این مجموعه کلاسها توسط برترین برنامه نویسان phpنوشته و عرضه میشن و تا مرحله پایداری بارها تست می شن به همین لحاظ از بسیاری از کلاسهای مشابه که در سایتهایی مثل phpclass و امثال اون پیدا می کنین برتری دارند

arash_hemmat
شنبه 12 فروردین 1385, 10:12 صبح
این مجموعه کلاسها توسط برترین برنامه نویسان phpنوشته و عرضه میشن و تا مرحله پایداری بارها تست می شن به همین لحاظ از بسیاری از کلاسهای مشابه که در سایتهایی مثل phpclass و امثال اون پیدا می کنین برتری دارند
منهم دقیقا میخواستم همین رو بگم ولی خوب در استفاده از کلاسهای pear واقعا مشکل دارم!

دوست عزیز وقتی قرار شد که از require_on,include_once دقت کن که دیگه هدف تو باز کردن کلاسهای نصب شده بر روی سرور نیست تو باید آدرس دقیق اون فایلها در اینجا مثلا Config.php رو بدی فراموش نکن آدرس دقیق
اگر به ارور کد بالا دقت کنید میبینید که روی سیستمی که روش pear نصب نیست برنامه در خط 3 متوقف میشه و ربطی به دادن آدرس کامل نداره (اضافه کردن این آدرس کاری نداره). حالا مشکل من اینه که قبل از include کردن یک کلاس pear چه جوری میتونم تست کنم ببینم که:
1-آیا pear روی سیستم نصب شده یا نه و نیازی به include کردن بست اصلی PEAR.php هست یا نه
2-آیا بسته مورد نظر نصب شده یا نه
چون با روشی که تو کد بالا امتحان کردم به محض اینکه به خط 3 برسه و اون بسته رو پیدا نکنه برنامه متوقف میشه.

oxygenws
شنبه 12 فروردین 1385, 10:15 صبح
دوما آخه کلاسهای پیر چه استفاده بشن چه نه برای من نفع یا ضرری نداره مسئله اینجاست که این ایراد از اون نیست از نحوه استفاده توسط شما برای همین من این تاکید رو دارم به هر شکل شما از چیز که دوست دارید می تونین استفاده کنین اما می خوام این رو هم بدونین که این مجموعه کلاسها توسط برترین برنامه نویسان phpنوشته و عرضه میشن و تا مرحله پایداری بارها تست می شن به همین لحاظ از بسیاری از کلاسهای مشابه که در سایتهایی مثل phpclass و امثال اون پیدا می کنین برتری دارند
من مخالف کلاس های پیر نیستم. می گم استفاده از اونها، شرایط خاصی می خواد که تقریبا هیچ کس مراقب نیست و توجه نمی کنه!
به نظر من استفاده کردن از تابعی که فایل های کانفیگ رو بخونه، مشکلی نداره، اما استفاده از توابع پایگاه داده اون، برای یک کار خصوصی و شخصی (برنامه تک کاره!) کار نادرستی است.

آرش، کلاس های پیر، یک سری کلاس کاملا عادی است و لازم نیست حتما روی سیستم نصب بشه. مثل کلاس های عادی باهاش برخورد کن.

در نهایت، تقریبا همیشه، من ترجیح می دم کلاس هام رو خودم بنویسم، تا (1) در اکثر اوقات بهینه تر باشه (2) در صورت تمایل با ایجاد تغییر در اون، کارم راحت باشه (3) بر تجربیاتم اضافه بشه. (4) ...

موفق باشید.

arash_hemmat
شنبه 12 فروردین 1385, 10:41 صبح
آرش، کلاس های پیر، یک سری کلاس کاملا عادی است و لازم نیست حتما روی سیستم نصب بشه. مثل کلاس های عادی باهاش برخورد کن.
خوشم میاد که شما هم مثل من حوصله ندارین کد مردم رو بخونین! بابا منم دوست دارم که با کلاسهای pear مثل کلاسهای معمولی رفتار کنم ولی خوب اینا طوری نوشته شدن که حتما باید pear رو سیستم نصب باشه تا کار کنن چون اولا همه اینا به کلاس اصلی PEAR.php وابسته اند و مثلا توی کلاس Config.php این کلاس رو اینطوری include کرده:
require_once('PEAR.php');
خوب چون مسیر این کلاس رو نداده روی سیستمی که pear روش نصب نباشه کار نمیکنه
ثانیا این کلاسها به فایلها و کلاسهای دیگه ای هم وابسته اند مثلا همین کلاس Config.php توی سطر دومش این فایل رو include کرده:
require_once('Config/Container.php');
و توی فایل Container.php دوباره توی سطر اول Config.php رو اینطوری صدا کرده:
require_once('Config.php');
تازه بعضی از بسته ها هستن که به چنتا بسته دیگه وابسته اند مثل بسته Auth.php که به DB.php وابسته هست و...
خوب اینطوری که نمیشه با این کلاسها مثل کلاسهای معمولی کار کرد! آیا شما راهی برای حل این مشکلات دارین؟

oxygenws
شنبه 12 فروردین 1385, 12:03 عصر
خوب اینطوری که نمیشه با این کلاسها مثل کلاسهای معمولی کار کرد! آیا شما راهی برای حل این مشکلات دارین؟
چرا نشه؟؟
ساختار چیزی جز همینی که می گی نیست. فایل ها رو به راحتی include کن!!

arash_hemmat
شنبه 12 فروردین 1385, 12:20 عصر
چرا نشه؟؟
ساختار چیزی جز همینی که می گی نیست. فایل ها رو به راحتی include کن!!
بابا نمیشه که آخه!
برای اینکه مثلا توی فایل Container.php فایل Config.php رو اینطوری include کرده:

require_once('Config.php');
در حالی که فایل Config.php رو باید اینطوری include کنه:

require_once('../Config.php');
چون Config.php یه دایرکتوری بالاتر از خودش قرار داره! برای اینکه توی اینطور include کردن مشکلی پیش نیاد باید عبارت Config.php یه predefined constant باشه که مقدارش به مسیر دقیق فایل Config.php اشاره کنه. با نصب pear روی سیستم این مقادیر به صورت predefined constant درمیان و هر جایی که خواستیم میتونیم کلاسهای pear رو فراخوانی کنیم بدون اینکه نیاز باشه مسیرشون رو به سیستم بگیم، ولی وقتی pear نصب نباشه نمیتونیم اینکار رو بکنیم در حالیکه توی خود کلاسها ازین روش استفاده شده و اگر بخوام اینکار رو دستی انجام بدم کلی کار داره که قبلا همه رو دستی تنظیم کردم و بازم کار نکرد!!!
خلاصه بد جوری شیر تو شیره! خودمم گیج شدم!

oxygenws
شنبه 12 فروردین 1385, 12:34 عصر
خوب تو فایل کانفیگ برنامه خودت، یک include_path به include_path های PHP اضافه کن.
اینا کمکت می کنند:
http://us2.php.net/manual/en/function.set-include-path.php
http://us2.php.net/manual/en/function.get-include-path.php
موفق باشی.

arash_hemmat
شنبه 12 فروردین 1385, 14:25 عصر
ممنونم اینهم دقیقا راهیه که تو راهنمای pear ذکر شده ،هنوز امتحانش نکردم،حتما امتحانش میکنم و نتیجش رو میگم.

arash_hemmat
شنبه 12 فروردین 1385, 15:38 عصر
امید تو طبق معمول یک Life Saver هستی :بوس: !!!
برنامه رو طوری نوشتم که اول با get_include_path چک کنه ببینه pear توی included pathها هست یا نه اگر نبود مسیر جایی رو که کلاسهای pear موردنظر رو اونجا گذاشتم رو به included pathها اضافه میکنم. اینطوری اگر pear نصب نباشه هم میتونم از کلاسهای pear استفاده بکنم بشرطی که اون کلاس و کلاسهایی رو که به اون مربوطند رو توی یه پوشه بریزم و آدرس اون پوشه رو به include pathها اضافه کنم. حاصل کار این کد بود:

<?php
// function to check if the pear package is installed
// returns true when pear liberary is included
function checkPearInstalled()
{
// get the list of included files
$included_files=ini_get('include_path');
// check if the package is included
if( eregi('pear',$included_files) )
return true;
return false;
}

// if the PEAR is not installed include it
if( !checkPearInstalled() )
{
ini_set('include_path', '/home/username/public_html/pear_test/pear');
echo 'The package is not included and it should be included manually.<br>';

}
else
echo 'The package is included and there is no need to include it.<br>';


// include PEAR Config
require_once('Config.php');
// test if Config package is working
$temp=array(
admin_name => 'admin',
admin_email => 'some_email_address'
);
$test = new Config();
$root =& $test->parseConfig($temp, "PHPArray");

if($test->writeConfig('test_conf.php','PHPArray'))
echo 'success<br>';
else
echo 'not abls to write configuration to file<br>';

include('test_conf.php');
echo $conf['admin_name'];
// if the Config package works it should display "admin"

?>
برای استفاده آیندگان کد کامل رو اینجا میزارم:

ramram
یک شنبه 13 فروردین 1385, 02:03 صبح
خوب خدا رو شکر امیدم تو بحثمون بود کارت لنگ نموند ولی من یه روز یه جا با این امید باید قرار بگذارم چند ده ساعت باهاش بحث کنم تا بفهمم اختلاف ما دوتا سر pear چیه اصلا اختلافی داریم ؟؟؟؟:متفکر: :لبخند: