পিএইচপি কোড ট্রান্সপিলিং জন্য চূড়ান্ত গাইড

আদর্শ পরিস্থিতিতে, আমাদের সমস্ত সাইটের জন্য PHP 8.0 (এটি লেখার সর্বশেষ সংস্করণ) ব্যবহার করা উচিত এবং একটি নতুন সংস্করণ প্রকাশিত হওয়ার সাথে সাথে এটি আপডেট করা উচিত। যাইহোক, ডেভেলপারদের প্রায়ই পূর্ববর্তী PHP সংস্করণগুলির সাথে কাজ করতে হবে, যেমন ওয়ার্ডপ্রেসের জন্য একটি পাবলিক প্লাগইন তৈরি করার সময় বা লিগ্যাসি কোডের সাথে কাজ করার সময় যা ওয়েব সার্ভারের পরিবেশকে আপগ্রেড করতে বাধা দেয়।
এই পরিস্থিতিতে, আমরা সর্বশেষ পিএইচপি কোড ব্যবহার করার আশা ছেড়ে দিতে পারি। কিন্তু একটি ভাল বিকল্প আছে: আমরা এখনও পিএইচপি 8.0 দিয়ে আমাদের সোর্স কোড লিখতে পারি এবং এটিকে পূর্ববর্তী পিএইচপি সংস্করণে স্থানান্তর করতে পারি - এমনকি পিএইচপি 7.1-তেও।
এই নির্দেশিকায়, আমরা আপনাকে পিএইচপি কোড ট্রান্সপাইলিং সম্পর্কে আপনার যা জানা দরকার তা শিখিয়ে দেব।
ট্রান্সপিলিং কি?
ট্রান্সপিলিং একটি প্রোগ্রামিং ভাষা থেকে সোর্স কোডকে একই বা একটি ভিন্ন প্রোগ্রামিং ভাষার সমতুল্য সোর্স কোডে রূপান্তর করে।
ওয়েব ডেভেলপমেন্টের মধ্যে ট্রান্সপিলিং একটি নতুন ধারণা নয়: ক্লায়েন্ট-সাইড ডেভেলপাররা সম্ভবত জাভাস্ক্রিপ্ট কোডের জন্য একটি ট্রান্সপিলার ব্যাবেলের সাথে পরিচিত হবে।
Babel আধুনিক ECMAScript 2015+ সংস্করণ থেকে জাভাস্ক্রিপ্ট কোডকে পুরানো ব্রাউজারগুলির সাথে সামঞ্জস্যপূর্ণ একটি লিগ্যাসি সংস্করণে রূপান্তর করে৷ উদাহরণস্বরূপ, একটি ES2015 তীর ফাংশন দেওয়া হয়েছে:
[2, 4, 6].map((n) => n * 2);
…ব্যাবেল এটিকে তার ES5 সংস্করণে রূপান্তর করবে:
[2, 4, 6].map(function(n) {
return n * 2;
});
Transpiling PHP কি?
ওয়েব ডেভেলপমেন্টের মধ্যে সম্ভাব্য নতুন যা হল সার্ভার-সাইড কোড, বিশেষ করে পিএইচপি ট্রান্সপিলিং করার সম্ভাবনা।
পিএইচপি ট্রান্সপিলিং জাভাস্ক্রিপ্ট ট্রান্সপিল করার মতো একইভাবে কাজ করে: একটি আধুনিক পিএইচপি সংস্করণ থেকে সোর্স কোড একটি পুরানো পিএইচপি সংস্করণের জন্য একটি সমতুল্য কোডে রূপান্তরিত হয়।
আগের মতো একই উদাহরণ অনুসরণ করে, PHP 7.4 থেকে একটি তীর ফাংশন:
$nums = array_map(fn($n) => $n * 2, [2, 4, 6]);
…এর সমতুল্য PHP 7.3 সংস্করণে স্থানান্তর করা যেতে পারে:
$nums = array_map(
function ($n) {
return $n * 2;
},
[2, 4, 6]
);
তীর ফাংশনগুলি স্থানান্তরিত হতে পারে কারণ সেগুলি সিনট্যাটিক চিনি, অর্থাৎ একটি বিদ্যমান আচরণ তৈরি করার জন্য একটি নতুন সিনট্যাক্স। এটি কম ঝুলন্ত ফল।
যাইহোক, সেখানে নতুন বৈশিষ্ট্য রয়েছে যা একটি নতুন আচরণ তৈরি করে এবং যেমন, পিএইচপি-এর পূর্ববর্তী সংস্করণগুলির জন্য কোন সমতুল্য কোড থাকবে না। পিএইচপি 8.0-তে চালু হওয়া ইউনিয়নের ধরনগুলির ক্ষেত্রে এটি হল:
function someFunction(float|int $param): string|float|int|null
{
// ...
}
এই পরিস্থিতিতে, ট্রান্সপিলিং এখনও করা যেতে পারে যতক্ষণ না নতুন বৈশিষ্ট্যটি বিকাশের জন্য প্রয়োজন তবে উত্পাদনের জন্য নয়। তারপরে, আমরা গুরুতর পরিণতি ছাড়াই ট্রান্সপাইল্ড কোড থেকে বৈশিষ্ট্যটিকে সম্পূর্ণরূপে সরিয়ে ফেলতে পারি।
এরকম একটি উদাহরণ হল ইউনিয়নের ধরন। এই বৈশিষ্ট্যটি পরীক্ষা করার জন্য ব্যবহার করা হয় যে ইনপুট প্রকার এবং এর প্রদত্ত মানের মধ্যে কোন মিল নেই, যা বাগ প্রতিরোধে সহায়তা করে। যদি প্রকারের সাথে কোন বিরোধ থাকে, তবে বিকাশে ইতিমধ্যেই একটি ত্রুটি থাকবে, এবং কোডটি উৎপাদনে পৌঁছানোর আগে আমাদের এটিকে ধরতে হবে এবং এটি ঠিক করতে হবে।
সুতরাং, আমরা উত্পাদনের জন্য কোড থেকে বৈশিষ্ট্যটি সরানোর সামর্থ্য রাখতে পারি:
function someFunction($param)
{
// ...
}
যদি এখনও উত্পাদনে ত্রুটিটি ঘটে, তবে নিক্ষেপ করা ত্রুটি বার্তাটি আমাদের ইউনিয়নের ধরনগুলির তুলনায় কম সুনির্দিষ্ট হবে। যাইহোক, এই সম্ভাব্য অসুবিধাটি প্রথম স্থানে ইউনিয়নের ধরনগুলি ব্যবহার করতে সক্ষম হওয়ার কারণে ছাড়িয়ে গেছে।
পিএইচপি কোড ট্রান্সপিলিং এর সুবিধা
ট্রান্সপিলিং একজনকে পিএইচপি-র সর্বশেষ সংস্করণ ব্যবহার করে একটি অ্যাপ্লিকেশন কোড করতে সক্ষম করে এবং একটি রিলিজ তৈরি করে যা PHP-এর পুরানো সংস্করণগুলি চলমান পরিবেশে কাজ করে।
লিগ্যাসি কন্টেন্ট ম্যানেজমেন্ট সিস্টেম (সিএমএস) এর জন্য পণ্য তৈরির ডেভেলপারদের জন্য এটি বিশেষভাবে উপযোগী হতে পারে। ওয়ার্ডপ্রেস, উদাহরণস্বরূপ, এখনও আনুষ্ঠানিকভাবে PHP 5.6 সমর্থন করে (যদিও এটি PHP 7.4+ সুপারিশ করে)। PHP সংস্করণ 5.6 থেকে 7.2 চলমান ওয়ার্ডপ্রেস সাইটগুলির শতাংশ - যেগুলি সমস্তই এন্ড-অফ-লাইফ (EOL), যার অর্থ তারা আর নিরাপত্তা আপডেট পাচ্ছে না - একটি বড় 34.8%, এবং যেগুলি অন্য কোনও PHP সংস্করণে চলছে 8.0 একটি সম্পূর্ণ 99.5% এ দাঁড়িয়েছে:

ফলস্বরূপ, বিশ্বব্যাপী শ্রোতাদের লক্ষ্য করে ওয়ার্ডপ্রেস থিম এবং প্লাগইনগুলি সম্ভবত তাদের সম্ভাব্য নাগাল বাড়ানোর জন্য PHP-এর একটি পুরানো সংস্করণের সাথে কোড করা হবে। ট্রান্সপিলিং করার জন্য ধন্যবাদ, এগুলি পিএইচপি 8.0 ব্যবহার করে কোড করা যেতে পারে এবং এখনও একটি পুরানো পিএইচপি সংস্করণের জন্য প্রকাশ করা যেতে পারে, এইভাবে যতটা সম্ভব ব্যবহারকারীকে লক্ষ্য করে।
প্রকৃতপক্ষে, যেকোন অ্যাপ্লিকেশন যা সাম্প্রতিকতম (এমনকি বর্তমানে সমর্থিত PHP সংস্করণগুলির সীমার মধ্যেও) ব্যতীত অন্য যেকোন পিএইচপি সংস্করণকে সমর্থন করতে হবে তা উপকৃত হতে পারে।
এটি ড্রুপালের ক্ষেত্রে, যার জন্য পিএইচপি 7.3 প্রয়োজন। ট্রান্সপিলিং করার জন্য ধন্যবাদ, বিকাশকারীরা PHP 8.0 ব্যবহার করে সর্বজনীনভাবে উপলব্ধ Drupal মডিউল তৈরি করতে পারে এবং সেগুলিকে PHP 7.3 দিয়ে প্রকাশ করতে পারে।
অন্য একটি উদাহরণ হল ক্লায়েন্টদের জন্য কাস্টম কোড তৈরি করার সময় যারা তাদের পরিবেশে PHP 8.0 চালাতে পারে না এক বা অন্য কারণে। তবুও, ট্রান্সপিলিং করার জন্য ধন্যবাদ, ডেভেলপাররা এখনও PHP 8.0 ব্যবহার করে তাদের ডেলিভারেবল কোড করতে পারে এবং সেই উত্তরাধিকার পরিবেশে চালাতে পারে।
কখন পিএইচপি ট্রান্সপিল করবেন
পিএইচপি কোড সর্বদা স্থানান্তরিত হতে পারে যদি না এতে কিছু পিএইচপি বৈশিষ্ট্য থাকে যা পিএইচপি-র পূর্ববর্তী সংস্করণের সমতুল্য না থাকে।
পিএইচপি 8.0 এ প্রবর্তিত বৈশিষ্ট্যগুলির ক্ষেত্রে এটি সম্ভবত:
#[SomeAttr]
function someFunc() {}
#[AnotherAttr]
class SomeClass {}
তীর ফাংশন ব্যবহার করে আগের উদাহরণে, কোডটি স্থানান্তরিত হতে পারে কারণ তীর ফাংশনগুলি সিনট্যাটিক চিনি। বৈশিষ্ট, বিপরীতে, সম্পূর্ণ নতুন আচরণ তৈরি করে। এই আচরণটি পিএইচপি 7.4 এবং নীচের সাথেও পুনরুত্পাদন করা যেতে পারে, তবে শুধুমাত্র ম্যানুয়ালি কোডিং করে, যেমন স্বয়ংক্রিয়ভাবে কোনও সরঞ্জাম বা প্রক্রিয়ার উপর ভিত্তি করে নয় (এআই একটি সমাধান দিতে পারে, তবে আমরা এখনও সেখানে নেই)।
উন্নয়ন ব্যবহারের জন্য অভিপ্রেত বৈশিষ্ট্য, যেমন #[Deprecated]
, ইউনিয়নের ধরনগুলি যেভাবে সরানো হয় একইভাবে সরানো যেতে পারে। কিন্তু প্রোডাকশনে অ্যাপ্লিকেশানের আচরণকে পরিবর্তন করে এমন বৈশিষ্ট্যগুলি সরানো যায় না এবং সেগুলি সরাসরি স্থানান্তরিতও হতে পারে না।
আজ অবধি, কোনও ট্রান্সপিলার পিএইচপি 8.0 বৈশিষ্ট্য সহ কোড নিতে পারে না এবং স্বয়ংক্রিয়ভাবে তার সমতুল্য পিএইচপি 7.4 কোড তৈরি করতে পারে না। ফলস্বরূপ, যদি আপনার পিএইচপি কোডের বৈশিষ্ট্যগুলি ব্যবহার করার প্রয়োজন হয়, তাহলে এটি স্থানান্তর করা কঠিন বা অসম্ভাব্য হবে।
পিএইচপি বৈশিষ্ট্য যা স্থানান্তর করা যেতে পারে
এগুলি হল পিএইচপি 7.1 এবং তার উপরের বৈশিষ্ট্য যা বর্তমানে স্থানান্তরিত হতে পারে। যদি আপনার কোড শুধুমাত্র এই বৈশিষ্ট্যগুলি ব্যবহার করে, আপনি নিশ্চিততা উপভোগ করতে পারেন যে আপনার ট্রান্সপিলড অ্যাপ্লিকেশন কাজ করবে। অন্যথায়, ট্রান্সপিলড কোড ব্যর্থতা তৈরি করবে কিনা তা আপনাকে মূল্যায়ন করতে হবে।
পিএইচপি সংস্করণ | বৈশিষ্ট্য |
---|---|
7.1 | সব |
7.2 | - object আদর্শ- পরামিতি প্রকার প্রশস্তকরণ - PREG_UNMATCHED_AS_NULL পতাকা preg_match |
7.3 | - এর মধ্যে রেফারেন্স অ্যাসাইনমেন্ট list() / অ্যারে ধ্বংস করা (ভিতরে ছাড়া foreach —#4376)- নমনীয় Heredoc এবং Nowdoc সিনট্যাক্স - ফাংশন কলে ট্র্যালিং কমা - set(raw)cookie $option আর্গুমেন্ট গ্রহণ করে |
7.4 | - টাইপ করা বৈশিষ্ট্য - তীর ফাংশন - নাল কোলেসিং অ্যাসাইনমেন্ট অপারেটর - অ্যারে ভিতরে আনপ্যাক করা - সংখ্যাসূচক আক্ষরিক বিভাজক - strip_tags() ট্যাগ নামের অ্যারের সাথে- কোভেরিয়েন্ট রিটার্ন প্রকার এবং বিরোধী পরাম প্রকার |
8.0 | - ইউনিয়ন প্রকার - mixed ছদ্ম প্রকার- static রিটার্ন টাইপ- ::class বস্তুর উপর জাদু ধ্রুবক- match এক্সপ্রেশন- catch ব্যতিক্রম শুধুমাত্র প্রকার দ্বারা- নাল-নিরাপদ অপারেটর - ক্লাস কনস্ট্রাক্টর সম্পত্তি প্রচার - পরামিতি তালিকা এবং ক্লোজারে কমা অনুসরণ করা use তালিকা |
পিএইচপি ট্রান্সপিলার
বর্তমানে, পিএইচপি কোড ট্রান্সপিল করার জন্য একটি টুল আছে: রেক্টর।
রেক্টর হল একটি পিএইচপি পুনর্গঠনকারী টুল, যা প্রোগ্রামেবল নিয়মের উপর ভিত্তি করে পিএইচপি কোড রূপান্তর করে। আমরা সোর্স কোড এবং চালানোর নিয়মের সেট ইনপুট করি এবং রেক্টর কোডটি রূপান্তরিত করবে।
রেক্টর কমান্ড লাইনের মাধ্যমে পরিচালিত হয়, কম্পোজারের মাধ্যমে প্রকল্পে ইনস্টল করা হয়। সম্পাদিত হলে, রেক্টর রূপান্তরের আগে এবং পরে কোডের একটি "ডিফ" (সবুজ রঙে সংযোজন, লাল রঙে অপসারণ) আউটপুট করবে:

পিএইচপি-এর কোন সংস্করণে ট্রান্সপিল করতে হবে
পিএইচপি সংস্করণ জুড়ে কোড ট্রান্সপিল করতে, সংশ্লিষ্ট নিয়মগুলি তৈরি করতে হবে।
আজ, রেক্টর লাইব্রেরিতে পিএইচপি 8.0 থেকে 7.1 এর মধ্যে কোড ট্রান্সপিলিং করার বেশিরভাগ নিয়ম অন্তর্ভুক্ত রয়েছে। সুতরাং, আমরা আমাদের পিএইচপি কোডকে 7.1 সংস্করণ পর্যন্ত নির্ভরযোগ্যভাবে ট্রান্সপিল করতে পারি।
পিএইচপি 7.1 থেকে 7.0 এবং 7.0 থেকে 5.6 পর্যন্ত ট্রান্সপিলিং করার জন্যও নিয়ম রয়েছে, তবে এগুলি সম্পূর্ণ নয়। সেগুলি সম্পূর্ণ করার জন্য কাজ চলছে, তাই আমরা শেষ পর্যন্ত PHP কোডটি 5.6 সংস্করণে ট্রান্সপিল করতে পারি।
ট্রান্সপিলিং বনাম ব্যাকপোর্টিং
ব্যাকপোর্টিং ট্রান্সপিলিংয়ের মতো, তবে সহজ। ব্যাকপোর্টিং কোড অগত্যা একটি ভাষা থেকে নতুন বৈশিষ্ট্য উপর নির্ভর করে না. পরিবর্তে, একই কার্যকারিতা শুধুমাত্র ভাষার নতুন সংস্করণ থেকে অনুলিপি/পেস্ট/অ্যাডাপ্ট করে ভাষার পুরানো সংস্করণে প্রদান করা যেতে পারে।
উদাহরণস্বরূপ, ফাংশন str_contains
পিএইচপি 8.0 এ চালু করা হয়েছিল। পিএইচপি 7.4 এবং নীচের জন্য একই ফাংশন সহজেই এই মত প্রয়োগ করা যেতে পারে:
if (!defined('PHP_VERSION_ID') || (defined('PHP_VERSION_ID') && PHP_VERSION_ID < 80000)) {
if (!function_exists('str_contains')) {
/**
* Checks if a string contains another
*
* @param string $haystack The string to search in
* @param string $needle The string to search
* @return boolean Returns TRUE if the needle was found in haystack, FALSE otherwise.
*/
function str_contains(string $haystack, string $needle): bool
{
return strpos($haystack, $needle) !== false;
}
}
}
যেহেতু ব্যাকপোর্টিং ট্রান্সপিলিংয়ের চেয়ে সহজ, তাই যখনই ব্যাকপোর্টিং কাজ করে তখন আমাদের এই সমাধানটি বেছে নেওয়া উচিত।
পিএইচপি 8.0 থেকে 7.1 এর মধ্যে পরিসরের বিষয়ে, আমরা সিমফনির পলিফিল লাইব্রেরি ব্যবহার করতে পারি:
- পলিফিল পিএইচপি 7.1
- পলিফিল পিএইচপি 7.2
- পলিফিল পিএইচপি 7.3
- পলিফিল পিএইচপি 7.4
- পলিফিল পিএইচপি 8.0
এই লাইব্রেরিগুলি নিম্নলিখিত ফাংশন, ক্লাস, ধ্রুবক এবং ইন্টারফেস ব্যাকপোর্ট করে:
পিএইচপি সংস্করণ | বৈশিষ্ট্য |
---|---|
7.2 | কার্যাবলী:
ধ্রুবক:
|
7.3 | কার্যাবলী:
ব্যতিক্রমসমূহ:
|
7.4 | কার্যাবলী:
|
8.0 | ইন্টারফেস:
ক্লাস:
ধ্রুবক:
কার্যাবলী:
|
Transpiled PHP এর উদাহরণ
চলুন ট্রান্সপিলড পিএইচপি কোডের কয়েকটি উদাহরণ এবং সম্পূর্ণভাবে ট্রান্সপিল করা হচ্ছে এমন কয়েকটি প্যাকেজ পরিদর্শন করা যাক।
পিএইচপি কোড
The Olymp Trade প্লার্টফর্মে ৩ টি উপায়ে প্রবেশ করা যায়। প্রথমত রয়েছে ওয়েব ভার্শন যাতে আপনি প্রধান ওয়েবসাইটের মাধ্যমে প্রবেশ করতে পারবেন। দ্বিতয়ত রয়েছে, উইন্ডোজ এবং ম্যাক উভয়ের জন্যেই ডেস্কটপ অ্যাপলিকেশন। এই অ্যাপটিতে রয়েছে অতিরিক্ত কিছু ফিচার যা আপনি ওয়েব ভার্শনে পাবেন না। এরপরে রয়েছে Olymp Trade এর এন্ড্রয়েড এবং অ্যাপল মোবাইল অ্যাপ। match
PHP 8.0 এ এক্সপ্রেশন চালু করা হয়েছিল। এই উৎস কোড:
function getFieldValue(string $fieldName): ?string
{
return match($fieldName) {
'foo' => 'foofoo',
'bar' => 'barbar',
'baz' => 'bazbaz',
default => null,
};
}
…এর সমতুল্য পিএইচপি 7.4 সংস্করণে স্থানান্তরিত করা হবে, ব্যবহার করে switch
অপারেটর:
function getFieldValue(string $fieldName): ?string
{
switch ($fieldName) {
case 'foo':
return 'foofoo';
case 'bar':
return 'barbar';
case 'baz':
return 'bazbaz';
default:
return null;
}
}
নালসেফ অপারেটরটি পিএইচপি 8.0-তেও চালু করা হয়েছিল:
public function getValue(TypeResolverInterface $typeResolver): ?string
{
return $this->getResolver($typeResolver)?->getValue();
}
ট্রান্সপিলড কোডটিকে প্রথমে একটি নতুন ভেরিয়েবলে অপারেশনের মান নির্ধারণ করতে হবে, যাতে অপারেশনটি দুবার চালানো এড়ানো যায়:
public function getValue(TypeResolverInterface $typeResolver): ?string
{
return ($val = $this->getResolver($typeResolver)) ? $val->getValue() : null;
}
কনস্ট্রাক্টর সম্পত্তি প্রচার বৈশিষ্ট্য, এছাড়াও PHP 8.0 তে চালু করা হয়েছে, ডেভেলপারদের কম কোড লিখতে অনুমতি দেয়:
class QueryResolver
{
function __construct(protected QueryFormatter $queryFormatter)
{
}
}
পিএইচপি 7.4 এর জন্য এটিকে স্থানান্তর করার সময়, কোডের সম্পূর্ণ অংশটি উত্পাদিত হয়:
class QueryResolver
{
protected QueryFormatter $queryFormatter;
function __construct(QueryFormatter $queryFormatter)
{
$this->queryFormatter = $queryFormatter;
}
}
উপরের ট্রান্সপিলড কোডে টাইপ করা বৈশিষ্ট্য রয়েছে, যা পিএইচপি 7.4 এ চালু করা হয়েছিল। সেই কোডটিকে পিএইচপি 7.3 এ স্থানান্তর করা হলে সেগুলিকে ডকব্লক দিয়ে প্রতিস্থাপন করা হয়:
class QueryResolver
{
/**
* @var QueryFormatter
*/
protected $queryFormatter;
function __construct(QueryFormatter $queryFormatter)
{
$this->queryFormatter = $queryFormatter;
}
}
পিএইচপি প্যাকেজ
নিম্নলিখিত গ্রন্থাগারগুলি উত্পাদনের জন্য স্থানান্তরিত হচ্ছে:
লাইব্রেরি/বর্ণনা | কোড/নোট |
---|---|
অধিশিক্ষক পিএইচপি পুনর্গঠনকারী টুল যা ট্রান্সপিলিং সম্ভব করে তোলে | - সোর্স কোড - স্থানান্তরিত কোড - মন্তব্য |
সহজ কোডিং মান পিএইচপি কোড থাকার টুলটি নিয়মের একটি সেট মেনে চলে | - সোর্স কোড - স্থানান্তরিত কোড - মন্তব্য |
ওয়ার্ডপ্রেসের জন্য গ্রাফকিউএল এপিআই ওয়ার্ডপ্রেসের জন্য একটি গ্রাফকিউএল সার্ভার প্রদানকারী প্লাগইন | - সোর্স কোড - স্থানান্তরিত কোড - মন্তব্য |
পিএইচপি ট্রান্সপিলিং এর সুবিধা এবং অসুবিধা
পিএইচপি ট্রান্সপিল করার সুবিধা ইতিমধ্যেই বর্ণনা করা হয়েছে: এটি সোর্স কোডকে PHP 8.0 (অর্থাৎ PHP-এর সর্বশেষ সংস্করণ) ব্যবহার করার অনুমতি দেয়, যা একটি লিগ্যাসি অ্যাপ্লিকেশন বা পরিবেশে উত্পাদন চালানোর জন্য PHP-এর জন্য একটি নিম্ন সংস্করণে রূপান্তরিত হবে।
এটি কার্যকরভাবে আমাদের আরও ভাল বিকাশকারী হতে দেয়, উচ্চ মানের সাথে কোড তৈরি করে। এর কারণ হল আমাদের সোর্স কোড PHP 8.0 এর ইউনিয়নের ধরন, PHP 7.4 এর টাইপ করা বৈশিষ্ট্য এবং PHP-এর প্রতিটি নতুন সংস্করণে যোগ করা বিভিন্ন প্রকার এবং ছদ্ম-টাইপ ব্যবহার করতে পারে (mixed
পিএইচপি 8.0 থেকে, object
পিএইচপি 7.2 থেকে), পিএইচপি-র অন্যান্য আধুনিক বৈশিষ্ট্যগুলির মধ্যে।
এই বৈশিষ্ট্যগুলি ব্যবহার করে, আমরা বিকাশের সময় বাগগুলি আরও ভালভাবে ধরতে পারি এবং কোড লিখতে পারি যা পড়া সহজ।
এখন, এর অপূর্ণতা কটাক্ষপাত করা যাক.
এটি অবশ্যই কোডেড এবং রক্ষণাবেক্ষণ করা উচিত
রেক্টর স্বয়ংক্রিয়ভাবে কোড ট্রান্সপাইল করতে পারে, কিন্তু প্রক্রিয়াটির জন্য সম্ভবত কিছু ম্যানুয়াল ইনপুট প্রয়োজন হবে যাতে এটি আমাদের নির্দিষ্ট সেটআপের সাথে কাজ করে।
থার্ড-পার্টি লাইব্রেরিগুলোও অবশ্যই ট্রান্সপিল করা উচিত
এটি একটি সমস্যা হয়ে দাঁড়ায় যখনই তাদের ট্রান্সপিল করা ত্রুটি তৈরি করে কারণ সম্ভাব্য কারণটি খুঁজে বের করার জন্য আমাদের অবশ্যই তাদের উত্স কোডটি অনুসন্ধান করতে হবে। যদি সমস্যাটি ঠিক করা যায় এবং প্রকল্পটি ওপেন সোর্স হয়, তাহলে আমাদের একটি পুল অনুরোধ জমা দিতে হবে। যদি লাইব্রেরিটি ওপেন সোর্স না হয়, তাহলে আমরা একটি রোডব্লককে আঘাত করতে পারি।
রেক্টর আমাদের জানান না যখন কোডটি স্থানান্তর করা যাবে না
যদি সোর্স কোডে PHP 8.0 বৈশিষ্ট্য বা অন্য কোনো বৈশিষ্ট্য থাকে যা স্থানান্তরিত করা যায় না, আমরা এগিয়ে যেতে পারি না। যাইহোক, রেক্টর এই শর্তটি পরীক্ষা করবেন না, তাই আমাদের এটি ম্যানুয়ালি করতে হবে। এটি আমাদের নিজস্ব সোর্স কোড সম্পর্কে একটি বড় সমস্যা নাও হতে পারে কারণ আমরা ইতিমধ্যে এটির সাথে পরিচিত, তবে এটি তৃতীয় পক্ষের নির্ভরতা সংক্রান্ত একটি বাধা হয়ে উঠতে পারে।
ডিবাগিং তথ্য ট্রান্সপিল্ড কোড ব্যবহার করে, সোর্স কোড নয়
যখন অ্যাপ্লিকেশনটি প্রোডাকশনে স্ট্যাক ট্রেস সহ একটি ত্রুটি বার্তা তৈরি করে, তখন লাইন নম্বরটি ট্রান্সপিল্ড কোডের দিকে নির্দেশ করবে। সোর্স কোডে সংশ্লিষ্ট লাইন নম্বর খুঁজতে আমাদের ট্রান্সপিল্ড থেকে আসল কোডে রূপান্তর করতে হবে।
Transpiled কোড এছাড়াও উপসর্গ করা আবশ্যক
আমাদের ট্রান্সপিলড প্রজেক্ট এবং কিছু অন্যান্য লাইব্রেরিও উৎপাদন পরিবেশে ইনস্টল করা একই তৃতীয় পক্ষের নির্ভরতা ব্যবহার করতে পারে এই তৃতীয় পক্ষের নির্ভরতা আমাদের প্রকল্পের জন্য স্থানান্তরিত হবে এবং অন্যান্য লাইব্রেরির জন্য এর মূল উত্স কোডটি রাখা হবে। তাই, সম্ভাব্য দ্বন্দ্ব এড়াতে PHP-Scoper, Strauss বা অন্য কোনো টুলের মাধ্যমে ট্রান্সপিলড সংস্করণটি অবশ্যই প্রিফিক্স করা উচিত।
ক্রমাগত ইন্টিগ্রেশন (CI) চলাকালীন স্থানান্তরিত হওয়া আবশ্যক
যেহেতু ট্রান্সপাইল্ড কোড স্বাভাবিকভাবেই সোর্স কোডকে ওভাররাইড করবে, তাই আমাদের ডেভেলপমেন্ট কম্পিউটারে ট্রান্সপিলিং প্রক্রিয়া চালানো উচিত নয়, অথবা আমরা পার্শ্বপ্রতিক্রিয়া সৃষ্টির ঝুঁকি নেব। একটি CI রানের সময় প্রক্রিয়াটি চালানো আরও উপযুক্ত (নীচে এটি সম্পর্কে আরও)।
কিভাবে পিএইচপি ট্রান্সপিল করবেন
প্রথমত, আমাদের উন্নয়নের জন্য আমাদের প্রকল্পে রেক্টর ইনস্টল করতে হবে:
composer require rector/rector --dev
আমরা তারপর একটি তৈরি rector.php
প্রজেক্টের রুট ডিরেক্টরীতে কনফিগারেশন ফাইল যাতে প্রয়োজনীয় নিয়ম সেট থাকে। PHP 8.0 থেকে 7.1 তে কোড ডাউনগ্রেড করতে, আমরা এই কনফিগারেশনটি ব্যবহার করি:
use RectorSetValueObjectDowngradeSetList;
use SymfonyComponentDependencyInjectionLoaderConfiguratorContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->import(DowngradeSetList::PHP_80);
$containerConfigurator->import(DowngradeSetList::PHP_74);
$containerConfigurator->import(DowngradeSetList::PHP_73);
$containerConfigurator->import(DowngradeSetList::PHP_72);
};
প্রত্যাশিতভাবে প্রক্রিয়াটি কার্যকর হয় তা নিশ্চিত করতে, আমরা রেক্টরস চালাতে পারি process
শুষ্ক মোডে কমান্ড, অবস্থান(গুলি) প্রক্রিয়া করার জন্য পাস করুন (এই ক্ষেত্রে, ফোল্ডারের অধীনে সমস্ত ফাইল src/
):
vendor/bin/rector process src --dry-run
ট্রান্সপিলিং সঞ্চালনের জন্য, আমরা রেক্টরের চালাই process
কমান্ড, যা ফাইলগুলিকে তাদের বিদ্যমান অবস্থানের মধ্যে পরিবর্তন করবে:
vendor/bin/rector process src
দয়া করে লক্ষ্য করুন: যদি আমরা চালাই rector process
আমাদের ডেভেলপমেন্ট কম্পিউটারে, সোর্স কোড জায়গায়, নিচে রূপান্তরিত হবে src/
. যাইহোক, আমরা কোড ডাউনগ্রেড করার সময় সোর্স কোডকে ওভাররাইড না করার জন্য একটি ভিন্ন স্থানে রূপান্তরিত কোড তৈরি করতে চাই। এই কারণে, ক্রমাগত একীকরণের সময় প্রক্রিয়া চালানো সবচেয়ে উপযুক্ত।
ট্রান্সপিলিং প্রক্রিয়া অপ্টিমাইজ করা
উৎপাদনের জন্য একটি ট্রান্সপাইল্ড ডেলিভারিযোগ্য উৎপন্ন করতে, শুধুমাত্র উৎপাদনের কোডটি রূপান্তর করতে হবে; শুধুমাত্র উন্নয়নের জন্য প্রয়োজনীয় কোড বাদ দেওয়া যেতে পারে। এর মানে আমরা সমস্ত পরীক্ষা (আমাদের প্রকল্প এবং এর নির্ভরতা উভয়ের জন্য) এবং বিকাশের জন্য সমস্ত নির্ভরতাকে ট্রান্সপিল করা এড়াতে পারি।
পরীক্ষাগুলির বিষয়ে, আমরা ইতিমধ্যেই জানতে পারব যে আমাদের প্রকল্পগুলি কোথায় অবস্থিত - উদাহরণস্বরূপ, ফোল্ডারের নীচে tests/
. আমাদের অবশ্যই খুঁজে বের করতে হবে যে নির্ভরতাগুলির জন্য কোথায় রয়েছে - উদাহরণস্বরূপ, তাদের সাবফোল্ডারের অধীনে tests/
, test/
এবং Test/
(বিভিন্ন লাইব্রেরির জন্য)। তারপর, আমরা রেক্টরকে বলি এই ফোল্ডারগুলি প্রক্রিয়াকরণ এড়িয়ে যেতে:
return static function (ContainerConfigurator $containerConfigurator): void {
// ...
$parameters->set(Option::SKIP, [
// Skip tests
'*/tests/*',
'*/test/*',
'*/Test/*',
]);
};
নির্ভরতা সম্পর্কিত, কম্পোজার জানেন কোনটি উন্নয়নের জন্য (যারা প্রবেশের অধীনে require-dev
in composer.json
) এবং কোনটি উৎপাদনের জন্য (যারা প্রবেশের অধীনে) require
).
কম্পোজার থেকে উত্পাদনের জন্য সমস্ত নির্ভরতার পথগুলি পুনরুদ্ধার করতে, আমরা চালাই:
composer info --path --no-dev
এই কমান্ডটি তাদের নাম এবং পথ সহ নির্ভরতার একটি তালিকা তৈরি করবে, যেমন:
brain/cortex /Users/leo/GitHub/leoloso/PoP/vendor/brain/cortex
composer/installers /Users/leo/GitHub/leoloso/PoP/vendor/composer/installers
composer/semver /Users/leo/GitHub/leoloso/PoP/vendor/composer/semver
guzzlehttp/guzzle /Users/leo/GitHub/leoloso/PoP/vendor/guzzlehttp/guzzle
league/pipeline /Users/leo/GitHub/leoloso/PoP/vendor/league/pipeline
আমরা সমস্ত পাথ বের করতে পারি এবং সেগুলিকে রেক্টর কমান্ডে ফিড করতে পারি, যা তারপরে আমাদের প্রকল্পের প্রক্রিয়া করবে src/
ফোল্ডার প্লাস সেই ফোল্ডারগুলি যেখানে উত্পাদনের জন্য সমস্ত নির্ভরতা রয়েছে:
$ paths="$(composer info --path --no-dev | cut -d' ' -f2- | sed 's/ //g' | tr 'n' ' ')"
$ vendor/bin/rector process src $paths
আরও উন্নতি রেক্টরকে ইতিমধ্যেই লক্ষ্য পিএইচপি সংস্করণ ব্যবহার করে সেই নির্ভরতাগুলি প্রক্রিয়াকরণ থেকে আটকাতে পারে। যদি একটি লাইব্রেরি PHP 7.1 (বা নীচের যেকোন সংস্করণ) দিয়ে কোড করা হয়, তাহলে এটিকে PHP 7.1-এ ট্রান্সপিল করার দরকার নেই।
এটি অর্জনের জন্য, আমরা PHP 7.2 এবং তার উপরে প্রয়োজনীয় লাইব্রেরিগুলির তালিকা পেতে পারি এবং শুধুমাত্র সেগুলি প্রক্রিয়া করতে পারি। আমরা এই সমস্ত লাইব্রেরির নাম কম্পোজার এর মাধ্যমে পেয়ে যাব why-not
আদেশ যেমন:
composer why-not php "7.1.*" | grep -o "S*/S*"
কারণ এই কমান্ডের সাথে কাজ করে না --no-dev
পতাকা, শুধুমাত্র উত্পাদনের জন্য নির্ভরতা অন্তর্ভুক্ত করতে, আমাদের প্রথমে বিকাশের জন্য নির্ভরতাগুলি সরিয়ে ফেলতে হবে এবং অটোলোডার পুনরায় তৈরি করতে হবে, কমান্ডটি চালাতে হবে এবং তারপরে সেগুলি আবার যুক্ত করতে হবে:
$ composer install --no-dev
$ packages=$(composer why-not php "7.1.*" | grep -o "S*/S*")
$ composer install
সুরকারের info --path
কমান্ড এই বিন্যাসের সাথে একটি প্যাকেজের জন্য পথ পুনরুদ্ধার করে:
# Executing this command
$ composer info psr/cache --path
# Produces this response:
psr/cache /Users/leo/GitHub/leoloso/PoP/vendor/psr/cache
ট্রান্সপিল করার সমস্ত পথ পেতে আমরা আমাদের তালিকার সমস্ত আইটেমের জন্য এই কমান্ডটি কার্যকর করি:
একটি হোস্টিং সমাধান প্রয়োজন যা আপনাকে একটি প্রতিযোগিতামূলক প্রান্ত দেয়? Behmasterআপনাকে অবিশ্বাস্য গতি, অত্যাধুনিক নিরাপত্তা, এবং স্বয়ংক্রিয় স্কেলিং দিয়ে আচ্ছাদিত করেছে৷ আমাদের পরিকল্পনা দেখুন
for package in $packages
do
path=$(composer info $package --path | cut -d' ' -f2-)
paths="$paths $path"
done
অবশেষে, আমরা এই তালিকাটি রেক্টরকে প্রদান করি (প্লাস প্রকল্পের src/
ফোল্ডার):
vendor/bin/rector process src $paths
কোড ট্রান্সপিলিং করার সময় ক্ষতিগুলি এড়াতে হবে
ট্রান্সপিলিং কোড একটি শিল্প হিসাবে বিবেচিত হতে পারে, প্রায়শই প্রকল্পের সাথে নির্দিষ্ট পরিবর্তনের প্রয়োজন হয়। আসুন আমরা কিছু সমস্যায় আসতে পারি তা দেখি।
শৃঙ্খলিত নিয়ম সবসময় প্রক্রিয়া করা হয় না
একটি শৃঙ্খলিত নিয়ম হল যখন একটি নিয়মকে পূর্ববর্তী নিয়ম দ্বারা উত্পাদিত কোডকে রূপান্তর করতে হবে।
উদাহরণস্বরূপ, লাইব্রেরি symfony/cache
এই কোড রয়েছে:
final class CacheItem implements ItemInterface
{
public function tag($tags): ItemInterface
{
// ...
return $this;
}
}
পিএইচপি 7.4 থেকে 7.3 পর্যন্ত ট্রান্সপিলিং করার সময়, ফাংশন tag
দুটি পরিবর্তনের মধ্য দিয়ে যেতে হবে:
- রিটার্ন টাইপ
ItemInterface
প্রথমে কনভার্ট করতে হবেself
, নিয়মের কারণেDowngradeCovariantReturnTypeRector
- রিটার্ন টাইপ
self
তারপর অপসারণ করা আবশ্যক, নিয়ম কারণেDowngradeSelfTypeDeclarationRector
শেষ ফলাফল এই এক হওয়া উচিত:
final class CacheItem implements ItemInterface
{
public function tag($tags)
{
// ...
return $this;
}
}
যাইহোক, রেক্টর শুধুমাত্র মধ্যবর্তী পর্যায়ে আউটপুট করে:
final class CacheItem implements ItemInterface
{
public function tag($tags): self
{
// ...
return $this;
}
}
সমস্যাটি হল যে রেক্টর সর্বদা নিয়মগুলি প্রয়োগ করা হয় তা নিয়ন্ত্রণ করতে পারে না।
সমাধান হল কোন শৃঙ্খলিত নিয়মগুলি প্রক্রিয়াবিহীন রেখে দেওয়া হয়েছিল তা চিহ্নিত করা এবং সেগুলি প্রয়োগ করার জন্য একটি নতুন রেক্টর চালানো।
শৃঙ্খলিত নিয়মগুলি সনাক্ত করতে, আমরা সোর্স কোডে দুবার রেক্টর চালাই, এইরকম:
$ vendor/bin/rector process src
$ vendor/bin/rector process src --dry-run
প্রথমবার, আমরা প্রত্যাশিত হিসাবে রেক্টর চালাই, ট্রান্সপিলিং চালানোর জন্য। দ্বিতীয়বার, আমরা ব্যবহার করি --dry-run
এখনও পরিবর্তন করা আছে কিনা তা আবিষ্কার করতে পতাকা। যদি থাকে, কমান্ডটি একটি ত্রুটি কোড সহ প্রস্থান করবে, এবং "ডিফ" আউটপুট নির্দেশ করবে কোন নিয়ম(গুলি) এখনও প্রয়োগ করা যেতে পারে। এর মানে হল যে প্রথম রান সম্পূর্ণ হয়নি, কিছু শৃঙ্খলিত নিয়ম প্রক্রিয়া করা হচ্ছে না।

একবার আমরা অপ্রয়োগিত শৃঙ্খলিত নিয়ম (বা নিয়ম) চিহ্নিত করার পরে, আমরা তারপরে আরেকটি রেক্টর কনফিগার ফাইল তৈরি করতে পারি - উদাহরণস্বরূপ, rector-chained-rule.php
অনুপস্থিত নিয়ম কার্যকর করবে। অধীনে সমস্ত ফাইলের জন্য নিয়মের একটি সম্পূর্ণ সেট প্রক্রিয়াকরণের পরিবর্তে src/
, এইবার, আমরা নির্দিষ্ট ফাইলে নির্দিষ্ট অনুপস্থিত নিয়মটি চালাতে পারি যেখানে এটি প্রয়োগ করা প্রয়োজন:
// rector-chained-rule.php
use RectorCoreConfigurationOption;
use RectorDowngradePhp74RectorClassMethodDowngradeSelfTypeDeclarationRector;
use SymfonyComponentDependencyInjectionLoaderConfiguratorContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(DowngradeSelfTypeDeclarationRector::class);
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::PATHS, [
__DIR__ . '/vendor/symfony/cache/CacheItem.php',
]);
};
অবশেষে, আমরা রেক্টরকে তার দ্বিতীয় পাসে ইনপুটের মাধ্যমে নতুন কনফিগারেশন ফাইলটি ব্যবহার করতে বলি --config
:
# First pass with all modifications
$ vendor/bin/rector process src
# Second pass to fix a specific problem
$ vendor/bin/rector process --config=rector-chained-rule.php
সুরকার নির্ভরতা অসামঞ্জস্যপূর্ণ হতে পারে
লাইব্রেরিগুলি বিকাশের জন্য একটি নির্ভরতা ঘোষণা করতে পারে (যেমন অধীনে require-dev
in composer.json
), তবুও এখনও, উৎপাদনের জন্য তাদের থেকে কিছু কোড উল্লেখ করুন (যেমন নীচের কিছু ফাইলে src/
, না tests/
).
সাধারণত, এটি কোনও সমস্যা নয় কারণ সেই কোডটি উৎপাদনে লোড নাও হতে পারে, তাই অ্যাপ্লিকেশনটিতে কোনও ত্রুটি থাকবে না। যাইহোক, যখন রেক্টর সোর্স কোড এবং এর নির্ভরতা প্রক্রিয়া করে, তখন এটি যাচাই করে যে সমস্ত রেফারেন্স কোড লোড করা যেতে পারে। রেক্টর একটি ত্রুটি নিক্ষেপ করবে যদি কোনো ফাইল একটি অ-ইনস্টলড লাইব্রেরি থেকে কোডের কিছু অংশ উল্লেখ করে (কারণ এটি শুধুমাত্র বিকাশের জন্য প্রয়োজন বলে ঘোষণা করা হয়েছিল)।
উদাহরণস্বরূপ, ক্লাস EarlyExpirationHandler
Symfony এর ক্যাশে কম্পোনেন্ট থেকে ইন্টারফেস প্রয়োগ করে MessageHandlerInterface
মেসেঞ্জার উপাদান থেকে:
class EarlyExpirationHandler implements MessageHandlerInterface
{
//...
}
যাহোক, symfony/cache
ঘোষণা symfony/messenger
উন্নয়নের জন্য নির্ভরতা হতে হবে। তারপর, যখন একটি প্রকল্পে রেক্টর চালানোর উপর নির্ভর করে symfony/cache
, এটি একটি ত্রুটি নিক্ষেপ করবে:
[ERROR] Could not process "vendor/symfony/cache/Messenger/EarlyExpirationHandler.php" file, due to:
"Analyze error: "Class SymfonyComponentMessengerHandlerMessageHandlerInterface not found.". Include your files in "$parameters->set(Option::AUTOLOAD_PATHS, [...]);" in "rector.php" config.
See https://github.com/rectorphp/rector#configuration".
এই সমস্যার তিনটি সমাধান আছে:
- রেক্টর কনফিগারেশনে, সেই ফাইলটি প্রসেসিং এড়িয়ে যান যা সেই কোডের অংশটিকে উল্লেখ করে:
return static function (ContainerConfigurator $containerConfigurator): void {
// ...
$parameters->set(Option::SKIP, [
__DIR__ . '/vendor/symfony/cache/Messenger/EarlyExpirationHandler.php',
]);
};
- অনুপস্থিত লাইব্রেরিটি ডাউনলোড করুন এবং রেক্টর দ্বারা স্বয়ংক্রিয়ভাবে লোড হওয়ার জন্য এর পথ যোগ করুন:
return static function (ContainerConfigurator $containerConfigurator): void {
// ...
$parameters->set(Option::AUTOLOAD_PATHS, [
__DIR__ . '/vendor/symfony/messenger',
]);
};
- আপনার প্রকল্পটি উত্পাদনের জন্য অনুপস্থিত লাইব্রেরির উপর নির্ভর করে:
composer require symfony/messenger
ট্রান্সপিলিং এবং ক্রমাগত ইন্টিগ্রেশন
আগেই বলা হয়েছে, আমাদের ডেভেলপমেন্ট কম্পিউটারে আমাদের অবশ্যই ব্যবহার করতে হবে --dry-run
রেক্টর চালানোর সময় পতাকা, বা অন্যথায়, ট্রান্সপিলড কোডের সাথে সোর্স কোড ওভাররাইড করা হবে। এই কারণে, ক্রমাগত ইন্টিগ্রেশন (CI) চলাকালীন প্রকৃত ট্রান্সপিলিং প্রক্রিয়া চালানোর জন্য এটি আরও উপযুক্ত, যেখানে আমরা প্রক্রিয়াটি চালানোর জন্য অস্থায়ী দৌড়বিদদের স্পিন করতে পারি।
আমাদের প্রকল্পের জন্য রিলিজ তৈরি করার সময় ট্রান্সপিলিং প্রক্রিয়া চালানোর একটি আদর্শ সময়। উদাহরণস্বরূপ, নীচের কোডটি গিটহাব অ্যাকশনগুলির জন্য একটি ওয়ার্কফ্লো, যা একটি ওয়ার্ডপ্রেস প্লাগইন প্রকাশ করে:
name: Generate Installable Plugin and Upload as Release Asset
on:
release:
types: [published]
jobs:
build:
name: Build, Downgrade and Upload Release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Downgrade code for production (to PHP 7.1)
run: |
composer install
vendor/bin/rector process
sed -i 's/Requires PHP: 7.4/Requires PHP: 7.1/' graphql-api.php
- name: Build project for production
run: |
composer install --no-dev --optimize-autoloader
mkdir build
- name: Create artifact
uses: montudor/action-zip@v0.1.0
with:
args: zip -X -r build/graphql-api.zip . -x *.git* node_modules/* .* "*/.*" CODE_OF_CONDUCT.md CONTRIBUTING.md ISSUE_TEMPLATE.md PULL_REQUEST_TEMPLATE.md rector.php *.dist composer.* dev-helpers** build**
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: graphql-api
path: build/graphql-api.zip
- name: Upload to release
uses: JasonEtco/upload-to-release@master
with:
args: build/graphql-api.zip application/zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
এই ওয়ার্কফ্লোতে গিটহাব অ্যাকশনের মাধ্যমে একটি ওয়ার্ডপ্রেস প্লাগইন প্রকাশ করার জন্য একটি আদর্শ পদ্ধতি রয়েছে। নতুন সংযোজন, PHP 7.4 থেকে 7.1 পর্যন্ত প্লাগইনের কোড ট্রান্সপিল করার জন্য, এই ধাপে ঘটে:
- name: Downgrade code for production (to PHP 7.1)
run: |
vendor/bin/rector process
sed -i 's/Requires PHP: 7.4/Requires PHP: 7.1/' graphql-api.php
একসাথে নেওয়া, এই কর্মপ্রবাহটি এখন নিম্নলিখিত পদক্ষেপগুলি সম্পাদন করে:
- পিএইচপি 7.4 দিয়ে লেখা একটি ওয়ার্ডপ্রেস প্লাগইন এর রিপোজিটরি থেকে সোর্স কোড পরীক্ষা করে
- এর কম্পোজার নির্ভরতা ইনস্টল করে
- এর কোড PHP 7.4 থেকে 7.1 পর্যন্ত ট্রান্সপিল করে
- থেকে প্লাগইনের প্রধান ফাইলের হেডারে "পিএইচপি প্রয়োজন" এন্ট্রি পরিবর্তন করে
"7.4"
থেকে"7.1"
- উন্নয়নের জন্য প্রয়োজনীয় নির্ভরতা দূর করে
- সমস্ত অপ্রয়োজনীয় ফাইল বাদ দিয়ে প্লাগইনের .zip ফাইল তৈরি করে
- .zip ফাইলটিকে রিলিজ সম্পদ হিসাবে আপলোড করে (এবং, উপরন্তু, GitHub অ্যাকশনে একটি শিল্পকর্ম হিসাবে)
ট্রান্সপিল্ড কোড পরীক্ষা করা হচ্ছে
একবার কোডটি PHP 7.1 এ স্থানান্তরিত হয়ে গেলে, আমরা কীভাবে জানব যে এটি ভাল কাজ করে? অথবা, অন্য কথায়, আমরা কীভাবে জানি যে এটি পুঙ্খানুপুঙ্খভাবে রূপান্তরিত হয়েছে, এবং পিএইচপি কোডের উচ্চতর সংস্করণগুলির কোন অবশিষ্টাংশ পিছনে অবশিষ্ট নেই?
কোড ট্রান্সপিল করার অনুরূপ, আমরা একটি CI প্রক্রিয়ার মধ্যে সমাধানটি বাস্তবায়ন করতে পারি। ধারণাটি হল রানার এনভায়রনমেন্ট পিএইচপি 7.1 দিয়ে সেট আপ করা এবং ট্রান্সপিল্ড কোডে একটি লিন্টার চালানো। যদি কোডের কোনো অংশ PHP 7.1 এর সাথে সামঞ্জস্যপূর্ণ না হয় (যেমন PHP 7.4 থেকে টাইপ করা সম্পত্তি যা রূপান্তরিত হয়নি), তাহলে লিন্টার একটি ত্রুটি ছুঁড়বে।
পিএইচপির জন্য একটি লিন্টার যা ভাল কাজ করে তা হল পিএইচপি প্যারালাল লিন্ট। আমরা এই লাইব্রেরিটি আমাদের প্রকল্পে বিকাশের জন্য নির্ভরতা হিসাবে ইনস্টল করতে পারি, অথবা CI প্রক্রিয়াটিকে এটি একটি স্বতন্ত্র কম্পোজার প্রকল্প হিসাবে ইনস্টল করতে পারি:
composer create-project php-parallel-lint/php-parallel-lint
যখনই কোডটিতে PHP 7.2 এবং তার উপরে থাকে, PHP প্যারালাল লিন্ট এইরকম একটি ত্রুটি নিক্ষেপ করবে:
Run php-parallel-lint/parallel-lint layers/ vendor/ --exclude vendor/symfony/polyfill-ctype/bootstrap80.php --exclude vendor/symfony/polyfill-intl-grapheme/bootstrap80.php --exclude vendor/symfony/polyfill-intl-idn/bootstrap80.php --exclude vendor/symfony/polyfill-intl-normalizer/bootstrap80.php --exclude vendor/symfony/polyfill-mbstring/bootstrap80.php
PHP 7.1.33 | 10 parallel jobs
............................................................ 60/2870 (2 %)
............................................................ 120/2870 (4 %)
...
............................................................ 660/2870 (22 %)
.............X.............................................. 720/2870 (25 %)
............................................................ 780/2870 (27 %)
...
............................................................ 2820/2870 (98 %)
.................................................. 2870/2870 (100 %)
Checked 2870 files in 15.4 seconds
Syntax error found in 1 file
------------------------------------------------------------
Parse error: layers/GraphQLAPIForWP/plugins/graphql-api-for-wp/graphql-api.php:55
53| '0.8.0',
54| __('GraphQL API for WordPress', 'graphql-api'),
> 55| ))) {
56| $plugin->setup();
57| }
Unexpected ')' in layers/GraphQLAPIForWP/plugins/graphql-api-for-wp/graphql-api.php on line 55
Error: Process completed with exit code 1.
আমাদের CI এর ওয়ার্কফ্লোতে লিন্টার যোগ করা যাক। পিএইচপি 8.0 থেকে 7.1 পর্যন্ত ট্রান্সপিল কোড চালানো এবং এটি পরীক্ষা করার পদক্ষেপগুলি হল:
- সোর্স কোড চেক আউট
- পরিবেশকে পিএইচপি 8.0 চালাতে দিন, যাতে রেক্টর সোর্স কোড ব্যাখ্যা করতে পারে
- কোডটি PHP 7.1 এ স্থানান্তর করুন
- পিএইচপি লিন্টার টুল ইনস্টল করুন
- পরিবেশের পিএইচপি সংস্করণ 7.1-এ স্যুইচ করুন
- ট্রান্সপিল্ড কোডে লিন্টার চালান
এই GitHub অ্যাকশন ওয়ার্কফ্লো কাজ করে:
name: Downgrade PHP tests
jobs:
main:
name: Downgrade code to PHP 7.1 via Rector, and execute tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set-up PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.0
coverage: none
- name: Local packages - Downgrade PHP code via Rector
run: |
composer install
vendor/bin/rector process
# Prepare for testing on PHP 7.1
- name: Install PHP Parallel Lint
run: composer create-project php-parallel-lint/php-parallel-lint --ansi
- name: Switch to PHP 7.1
uses: shivammathur/setup-php@v2
with:
php-version: 7.1
coverage: none
# Lint the transpiled code
- name: Run PHP Parallel Lint on PHP 7.1
run: php-parallel-lint/parallel-lint src/ vendor/ --exclude vendor/symfony/polyfill-ctype/bootstrap80.php --exclude vendor/symfony/polyfill-intl-grapheme/bootstrap80.php --exclude vendor/symfony/polyfill-intl-idn/bootstrap80.php --exclude vendor/symfony/polyfill-intl-normalizer/bootstrap80.php --exclude vendor/symfony/polyfill-mbstring/bootstrap80.php
যে কয়েকটি লক্ষ্য করুন bootstrap80.php
সিমফনির পলিফিল লাইব্রেরি থেকে ফাইলগুলি (যা ট্রান্সপিল করা দরকার নেই) অবশ্যই লিন্টার থেকে বাদ দিতে হবে। এই ফাইলগুলিতে পিএইচপি 8.0 রয়েছে, তাই লিন্টারটি প্রক্রিয়া করার সময় ত্রুটিগুলি নিক্ষেপ করবে। যাইহোক, এই ফাইলগুলি বাদ দেওয়া নিরাপদ কারণ এগুলি শুধুমাত্র PHP 8.0 বা তার উপরে চালানোর সময় উৎপাদনে লোড হবে:
if (PHP_VERSION_ID >= 80000) {
return require __DIR__.'/bootstrap80.php';
}
সারাংশ
এই নিবন্ধটি আমাদের শিখিয়েছে কিভাবে আমাদের পিএইচপি কোড ট্রান্সপিল করতে হয়, যাতে আমরা সোর্স কোডে পিএইচপি 8.0 ব্যবহার করতে পারি এবং পিএইচপি 7.1-এ কাজ করে এমন একটি রিলিজ তৈরি করতে পারি। ট্রান্সপিলিং রেক্টরের মাধ্যমে করা হয়, একটি পিএইচপি পুনর্গঠনকারী টুল।
আমাদের কোড ট্রান্সপিল করা আমাদের আরও ভাল বিকাশকারী করে তোলে কারণ আমরা বিকাশে বাগগুলি আরও ভালভাবে ধরতে পারি এবং এমন কোড তৈরি করতে পারি যা স্বাভাবিকভাবেই পড়া এবং বোঝা সহজ।
ট্রান্সপিলিং আমাদের সিএমএস থেকে নির্দিষ্ট পিএইচপি প্রয়োজনীয়তার সাথে আমাদের কোডকে ডিকপল করতে সক্ষম করে। আমরা এখন তা করতে পারি যদি আমরা আমাদের ইউজারবেসকে মারাত্মকভাবে সীমাবদ্ধ না করে একটি সর্বজনীনভাবে উপলব্ধ ওয়ার্ডপ্রেস প্লাগইন বা ড্রুপাল মডিউল তৈরি করতে PHP-এর সর্বশেষ সংস্করণ ব্যবহার করতে চাই।
পিএইচপি ট্রান্সপিলিং সম্পর্কে আপনার কি কোন প্রশ্ন বাকি আছে? আমাদের মন্তব্য বিভাগে জানতে দিন!