এই ত্রুটিটি কারও মধ্যে চলে যেতে পারে তার অনেকগুলি কারণ রয়েছে এবং সুতরাং প্রথমে কী চেক করা উচিত তার একটি ভাল চেকলিস্ট যথেষ্ট পরিমাণে সহায়তা করে।
আসুন বিবেচনা করা যাক আমরা নিম্নলিখিত লাইনের সমস্যা সমাধান করছি:
require "/path/to/file"
চেকলিস্ট
টাইপসের জন্য ফাইলের পাথটি পরীক্ষা করুন
- হয় ম্যানুয়ালি পরীক্ষা করুন (চাক্ষুষভাবে পথ পরীক্ষা করে)
বা যাকে বলা হয় require*
বা include*
তার নিজস্ব ভেরিয়েবলে স্থানান্তর করুন , এটি প্রতিধ্বনি করুন, অনুলিপি করুন এবং টার্মিনাল থেকে এটি অ্যাক্সেস করার চেষ্টা করুন:
$path = "/path/to/file";
echo "Path : $path";
require "$path";
তারপরে, একটি টার্মিনালে:
cat <file path pasted>
২. পরীক্ষা করুন বনাম পরম পাথ বিবেচনার ক্ষেত্রে ফাইলের পথটি সঠিক কিনা
- যদি এটি একটি ফরোয়ার্ড স্ল্যাশ "/" দ্বারা শুরু হয় তবে এটি আপনার ওয়েবসাইটের ফোল্ডারের (ডকুমেন্ট রুট) মূলকে নির্দেশ করে না, তবে আপনার সার্ভারের মূলকে বোঝায়।
- উদাহরণস্বরূপ, আপনার ওয়েবসাইটের ডিরেক্টরি হতে পারে
/users/tony/htdocs
- যদি এটি কোনও ফরোয়ার্ড স্ল্যাশ দিয়ে শুরু না হয় তবে তা হয় অন্তর্ভুক্ত পাথের উপর নির্ভর করে (নীচে দেখুন) বা পথটি আপেক্ষিক। যদি এটি আপেক্ষিক হয়, তবে পিএইচপি বর্তমান কার্যক্ষম ডিরেক্টরিটির পথে তুলনামূলকভাবে গণনা করবে ।
- সুতরাং, আপনার ওয়েবসাইটের মূলের পাথের সাথে বা আপনি যে ফাইলটি টাইপ করছেন তার সাথে সম্পর্কিত নয়
- যে কারণে, সর্বদা নিখুঁত ফাইল পাথ ব্যবহার করুন
সেরা অনুশীলন :
রান স্ক্রিনে এখনও কোনও পরম পথ তৈরি করার সময় আপনার জিনিসগুলি চারদিকে সরিয়ে নেওয়ার ক্ষেত্রে আপনার স্ক্রিপ্টটি শক্তিশালী করার জন্য আপনার কাছে দুটি বিকল্প রয়েছে:
- ব্যবহার
require __DIR__ . "/relative/path/from/current/file"
। __DIR__
জাদু ধ্রুবক বর্তমান ফাইলের ডিরেক্টরি ফেরৎ।
একটি SITE_ROOT
ধ্রুবক নিজেকে সংজ্ঞায়িত করুন:
- আপনার ওয়েবসাইটের ডিরেক্টরিটির মূলে একটি ফাইল তৈরি করুন, যেমন
config.php
ইন config.php
, লিখুন
define('SITE_ROOT', __DIR__);
প্রতিটি ফাইলে যেখানে আপনি সাইটের মূল ফোল্ডারটি উল্লেখ করতে চান, অন্তর্ভুক্ত করুন config.php
এবং তারপরে SITE_ROOT
যেখানে খুশি সেখানে ধ্রুবকটি ব্যবহার করুন :
require_once __DIR__."/../config.php";
...
require_once SITE_ROOT."/other/file.php";
এই 2 টি অনুশীলনগুলি আপনার অ্যাপ্লিকেশনটিকে আরও পোর্টেবল করে তোলে কারণ এটি অন্তর্ভুক্ত পাথের মতো আইএনআই সেটিংসে নির্ভর করে না।
৩. আপনার অন্তর্ভুক্ত পথটি পরীক্ষা করুন
ফাইলগুলি অন্তর্ভুক্ত করার আরেকটি উপায়, তুলনামূলকভাবে বা সম্পূর্ণ নিখুঁতভাবে নয়, অন্তর্ভুক্ত পথে নির্ভর করা । এটি প্রায়শই লাইব্রেরি বা ফ্রেমওয়ার্ক যেমন জেন্ড ফ্রেমওয়ার্কের ক্ষেত্রে ঘটে।
এই জাতীয় অন্তর্ভুক্তি দেখতে এটি দেখতে পাবেন:
include "Zend/Mail/Protocol/Imap.php"
সেক্ষেত্রে, আপনি নিশ্চিত করতে চাইবেন যে "ফোকাস" যেখানে ফোল্ডারটি অন্তর্ভুক্ত পথের অংশ।
আপনি এর সাথে অন্তর্ভুক্ত পথটি পরীক্ষা করতে পারেন:
echo get_include_path();
আপনি এটির সাথে একটি ফোল্ডার যুক্ত করতে পারেন:
set_include_path(get_include_path().":"."/path/to/new/folder");
৪. আপনার সার্ভারের সেই ফাইলটিতে অ্যাক্সেস রয়েছে কিনা তা পরীক্ষা করুন
এটি সমস্ত একসাথে হয়ে থাকতে পারে, সার্ভার প্রক্রিয়া চালিয়ে ব্যবহারকারীর (অ্যাপাচি বা পিএইচপি) কেবল সেই ফাইলটি থেকে পড়ার বা লেখার অনুমতি নেই।
সার্ভারটি কোন ব্যবহারকারীর দ্বারা চলছে তা পরীক্ষা করতে আপনি posix_getpwuid ব্যবহার করতে পারেন :
$user = posix_getpwuid(posix_geteuid());
var_dump($user);
ফাইলটিতে অনুমতিগুলি খুঁজতে, টার্মিনালে নিম্নলিখিত কমান্ডটি টাইপ করুন:
ls -l <path/to/file>
এবং অনুমতি প্রতীকী স্বরলিপি তাকান
৫. পিএইচপি সেটিংস পরীক্ষা করুন
যদি উপরের কোনওটি যদি কাজ না করে, তবে সমস্যাটি সম্ভবত এমন হয় যে কিছু পিএইচপি সেটিংস সেটিকে ফাইলটিতে অ্যাক্সেস করতে নিষেধ করে।
তিনটি সেটিংস প্রাসঙ্গিক হতে পারে:
- open_basedir
- যদি এটি সেট করা থাকে তবে পিএইচপি নির্দিষ্ট ডিরেক্টরিের বাইরে কোনও ফাইল অ্যাক্সেস করতে সক্ষম হবে না (এমনকি প্রতীকী লিঙ্কের মাধ্যমেও নয়)।
- যাইহোক, ডিফল্ট আচরণ এটি নির্ধারণ না করা হয় যে ক্ষেত্রে কোনও সীমাবদ্ধতা নেই
- এটি ফোন করে
phpinfo()
বা ব্যবহার করে চেক করা যেতে পারেini_get("open_basedir")
- আপনি আপনার php.ini ফাইল বা আপনার httpd.conf ফাইল সম্পাদনা করে সেটিংস পরিবর্তন করতে পারেন
- নিরাপদ ভাবে
- এটি নিষ্ক্রিয় করা থাকলে এটি প্রয়োগ হতে পারে। তবে এটি পিএইচপি 5.4 এ সরানো হয়েছে। আপনি যদি এখনও এমন কোনও সংস্করণে থাকেন যা কোনও পিএইচপি সংস্করণে নিরাপদ মোড আপগ্রেড সমর্থন করে যা এখনও সমর্থনযোগ্য ।
- اجازه_url_fopen এবং অনুমতি_url_ সহ অন্তর্ভুক্ত
- এটি কেবলমাত্র স্থানীয় নেটওয়ার্ক সিস্টেমে ফাইল অন্তর্ভুক্ত করার চেষ্টা করার সময় নয়: HTTP: // এর মতো নেটওয়ার্ক প্রক্রিয়ার মাধ্যমে ফাইলগুলি অন্তর্ভুক্ত বা খোলার ক্ষেত্রে প্রযোজ্য
- এটি দিয়ে চেক করা যায়
ini_get("allow_url_include")
এবং সেট করা যায়ini_set("allow_url_include", "1")
কর্নার কেস
উপরের কোনওটি যদি সমস্যা নির্ণয়ের জন্য সক্ষম না হয় তবে এখানে কিছু বিশেষ পরিস্থিতি রয়েছে যা ঘটতে পারে:
1. পাঠাগারে অন্তর্ভুক্ত লাইব্রেরি অন্তর্ভুক্তি
এটি ঘটতে পারে যে আপনি একটি লাইব্রেরি অন্তর্ভুক্ত করেন, উদাহরণস্বরূপ, জেন্ড ফ্রেমওয়ার্ক, আপেক্ষিক বা পরম পথ ব্যবহার করে। উদাহরণ স্বরূপ :
require "/usr/share/php/libzend-framework-php/Zend/Mail/Protocol/Imap.php"
তবে তারপরেও আপনি একই ধরণের ত্রুটি পান।
এটি ঘটতে পারে কারণ আপনি যে ফাইলটি (সাফল্যের সাথে) অন্তর্ভুক্ত করেছেন সেটির অন্য একটি ফাইলের নিজেই একটি অন্তর্ভুক্ত বিবৃতি রয়েছে এবং দ্বিতীয়টিতে বিবৃতিটি অন্তর্ভুক্ত করে ধরে নেওয়া হয় যে আপনি সেই লাইব্রেরির পথটি অন্তর্ভুক্ত করার পথে যুক্ত করেছেন।
উদাহরণস্বরূপ, পূর্বে উল্লিখিত জেন্ড ফ্রেমওয়ার্ক ফাইলে নিম্নলিখিতগুলির মধ্যে অন্তর্ভুক্ত থাকতে পারে:
include "Zend/Mail/Protocol/Exception.php"
যা না কোনও আপেক্ষিক পথ দ্বারা অন্তর্ভুক্ত নয়, না পরম পথ দ্বারা। এটি ধরে নেওয়া হচ্ছে যে জেন্ড ফ্রেমওয়ার্ক ডিরেক্টরিটি অন্তর্ভুক্তের পথে যুক্ত করা হয়েছে।
এই জাতীয় ক্ষেত্রে, কেবলমাত্র কার্যকর সমাধান হ'ল ডিরেক্টরিটি আপনার অন্তর্ভুক্ত পথে যুক্ত করা add
2. সেলিনাক্স
আপনি যদি সুরক্ষা-বর্ধিত লিনাক্স চালাচ্ছেন তবে সার্ভার থেকে ফাইল অ্যাক্সেসকে অস্বীকার করে সমস্যাটির কারণ হতে পারে।
আপনার সিস্টেমে SELinux সক্ষম আছে কিনা তা পরীক্ষা করতেsestatus
একটি টার্মিনালে কমান্ডটি চালান । যদি কমান্ডটি উপস্থিত না থাকে, তবে SELinux আপনার সিস্টেমে নেই। যদি এটি বিদ্যমান থাকে, তবে এটি প্রয়োগ করা হবে কি না তা আপনাকে জানানো উচিত।
SELinux নীতিগুলি সমস্যার কারণ কিনা তা যাচাই করতে আপনি এটি অস্থায়ীভাবে বন্ধ করার চেষ্টা করতে পারেন। তবে সাবধান থাকুন, কারণ এটি পুরোপুরি সুরক্ষা অক্ষম করবে। আপনার প্রোডাকশন সার্ভারে এটি করবেন না।
setenforce 0
আপনার যদি আর সেলইনাক্স বন্ধ হওয়ার সমস্যা না থেকে থাকে তবে এটির মূল কারণ।
এটি সমাধান করতে , আপনাকে সে অনুযায়ী সেলইনাক্স কনফিগার করতে হবে।
নিম্নলিখিত প্রসঙ্গে প্রকারের প্রয়োজন হবে:
httpd_sys_content_t
আপনার সার্ভারটি পড়তে সক্ষম হতে চান এমন ফাইলগুলির জন্য
httpd_sys_rw_content_t
যে ফাইলগুলিতে আপনি পড়তে এবং লেখার অ্যাক্সেস চান তার জন্য
httpd_log_t
লগ ফাইলের জন্য
httpd_cache_t
ক্যাশে ডিরেক্টরি জন্য
উদাহরণস্বরূপ, httpd_sys_content_t
আপনার ওয়েবসাইটের মূল ডিরেক্টরিতে প্রসঙ্গের প্রকারটি নির্ধারণ করতে , চালান:
semanage fcontext -a -t httpd_sys_content_t "/path/to/root(/.*)?"
restorecon -Rv /path/to/root
যদি আপনার ফাইলটি কোনও হোম ডিরেক্টরিতে থাকে তবে আপনাকে httpd_enable_homedirs
বুলিয়ানও চালু করতে হবে :
setsebool -P httpd_enable_homedirs 1
যাই হোক না কেন, নীতিগুলির উপর নির্ভর করে SELinux কোনও ফাইল অ্যাক্সেস অস্বীকার করার বিভিন্ন কারণ থাকতে পারে। সুতরাং আপনার এটি অনুসন্ধান করতে হবে। এখানে একটি ওয়েব সার্ভারের জন্য SELinux কনফিগার করার বিষয়ে একটি টিউটোরিয়াল রয়েছে।
3. সিমফনি
আপনি যদি সিমফনি ব্যবহার করছেন এবং কোনও সার্ভারে আপলোড করার সময় এই ত্রুটিটি অনুভব করছেন, তবে এটি এমন হতে পারে যে অ্যাপ্লিকেশনটির ক্যাশে পুনরায় সেট করা হয়নি, হয় app/cache
আপলোড হয়ে গেছে বা ক্যাশে সাফ করা হয়নি।
আপনি নিম্নলিখিত কনসোল কমান্ডটি চালিয়ে এটি পরীক্ষা করে ঠিক করতে পারেন:
cache:clear
৪. জিপ ফাইলের মধ্যে নন এসিএসআইআই অক্ষর
স্পষ্টতই, zip->close()
জিপের অভ্যন্তরে কিছু ফাইলের "é" এর মতো ফাইলের নামগুলিতে অ-এএসসিআইআই অক্ষর না থাকলে কল করার সময়ও এই ত্রুটি ঘটতে পারে ।
একটি সম্ভাব্য সমাধান হ'ল utf8_decode()
লক্ষ্য ফাইলটি তৈরি করার আগে ফাইলটির নাম মোড়ানো ।
এই সমস্যার সমাধান সনাক্তকরণ এবং পরামর্শ দেওয়ার জন্য ফ্র্যান ক্যানোকে ক্রেডিট