সরাসরি সুপারগ্লোবালগুলি সংশোধন করা হচ্ছে


20

আমি লোককে (যারা সাধারণত ভাল কোড লেখেন) সরাসরি $_POSTএই জাতীয় কোড দিয়ে অ্যারে পরিবর্তন করে দেখেছেন :

// Add some value that wasn't actually posted
$_POST['last_activity'] = time();

// Alter an existing post value
$_POST['name'] = trim($_POST['name']);

// Our pretend function
// Pass the entire $_POST array as data to work with in the function
// The function update_record() will read only the values we actually need
update_record($_POST);

// ...That sure was easier than creating a new array 
//  with only the $_POST values we actually need.

এটি উপলব্ধি করে যে update_record()$ _POST সরাসরি অ্যাক্সেস করা উচিত নয়, সুতরাং উদাহরণস্বরূপ আমরা এটিতে অন্যান্য ডেটার অ্যারে পাস করতে পারি, তবে অবশ্যই এটি অলস, খারাপ নকশা, বা সম্ভবত ভুল? যাইহোক, আমরা এখনও একটি বৈধ অ্যারে পাস করছি update_record(), সুতরাং কেন একটি নতুন তৈরি করবেন?

এটি প্রশ্নের বিন্দু নয়, কেবল ব্যবহারের উদাহরণ। তবে, আমি প্রচুর লোককে বলতে শুনেছি যে $_REQUESTএটি ডেটা দিয়ে করা উচিত নয় এবং এটি খারাপ অভ্যাস। কিন্তু কেন? যথেষ্ট নিরীহ দেখাচ্ছে।

উদাহরণ:

  • একটি ডিফল্ট $_GET(বা পোস্ট) মান সেট করা যা সত্যই বিদ্যমান নেই

  • $_POSTফর্ম জমা দেওয়ার পরে পোস্ট করা হয়নি এমন মান যুক্ত করা হচ্ছে

  • স্ক্রিপ্টের খুব প্রথম দিকে $_GETঅ্যারে মান বা কীগুলি সরাসরি স্যানিটাইজিং বা ফিল্টারিং করা (ফলব্যাক স্যানিটেশন ... কেন নয়?)

  • $_POSTএকটি ডিফল্ট মান সহ কোনও ইনপুট পপুলেট করার জন্য ফর্ম জমা দেওয়ার আগে ম্যানুয়ালি একটি মান সেট করা (যখন ইনপুটটি $_POSTএটির ডিফল্ট মানের জন্য পড়ে ; আমি এটি করেছি)

  • নিজের $_SERVERমূল্যবোধ তৈরি? অবশ্যই, আরে কেন?

  • অন্যদের মত, $_COOKIEএবং মত $_SESSION? অবশ্যই আমরা সরাসরি তাদের সংশোধন করতে হবে? তাহলে অন্যরা কেন নয়?

সুপারগ্লোবালগুলির সরাসরি সংশোধন করা কখনই করা উচিত নয়, বা কিছু ক্ষেত্রে করা ঠিক আছে ?


আমি # 1, # 2 এবং # 3 এর সাথে একমত হব কারণ এটি অপ্রত্যাশিত ব্যবহার (বিশেষত # 1 এবং # 2)।
কেভিন পেনো

ভাল প্রশ্ন. গ্লোবাল অ্যারেগুলি সংশোধন করা একইভাবে বৈশ্বিক মান ব্যবহার করা ভুল। এছাড়াও এই অ্যারেগুলির উদ্দেশ্য রয়েছে (বাইরে থেকে পরামিতিগুলি পেরিয়ে যাওয়া) যা তাদের কোডের মধ্যে বিশৃঙ্খলার সোজা উপায় পরিবর্তন করে makes তবে, আমি বিশ্বাস করি যে এই অ্যারেগুলির কিছু স্ক্রিপ্টের সূচনাতে স্যানিটাইজ করা যেতে পারে, কেবল কোডের মধ্যে সমস্যা তৈরি করতে নয়।
টেডেক

1
আমি ও ইনপুট অ্যারে র‌্যাপারগুলি (অন্তর্নিহিত ফিল্টারিং) ব্যবহার করছি, যা additional _GET বা $ _POST ভেরিয়েবলের সাথে টেম্পার করার সময় একটি অতিরিক্ত নোটিশ প্রিন্ট করে। এটি এখনও সম্ভব, তবে সংকীর্ণ পরিস্থিতিতে সীমাবদ্ধ থাকা উচিত। (ক্রস-মডিউল সিগন্যালিং, তবে কেবল প্রেরণকারী / সামনের নিয়ামকের প্রয়োজন হওয়া উচিত
মারিও

@ মারিও: আপনি কীভাবে সফল হয়েছেন সে সম্পর্কে আমি আরও শুনতে আগ্রহী যে আপনি যদি এই প্রশ্নটি একবার দেখে নিতে পারেন: স্ট্যাকওভারফ্লো
ওয়েসলি মার্চ

উত্তর:


16

পিএইচপি ইতিমধ্যে এই সুপারগ্লোবালগুলি সেট করে দিচ্ছে, এগুলি সংশোধন করা খারাপ বলে আমি মনে করি না । কিছু ক্ষেত্রে সমস্যাগুলি সমাধান করার সর্বোত্তম উপায় হতে পারে ... বিশেষত যখন আপনি সহজেই সংশোধন করতে পারবেন না তৃতীয় পক্ষের কোডের সাথে ডিল করার সময়। (তারা $_GETসরাসরি ব্যবহার করতে পারে বা ধরে নিতে পারে যে কোনও কী কী রয়েছে $_SERVER) ইত্যাদি)

তবে, সাধারণভাবে বলতে গেলে, আমি মনে করি যে আপনি নিজের কোডটি লেখার সময় এটি একটি খারাপ অভ্যাস। $_REQUESTপ্রতিটি পৃষ্ঠায় স্বয়ংক্রিয়ভাবে চলমান পর্দার ফিল্টারগুলির পিছনে কিছু দিয়ে ডেটা পরিবর্তন করে পার্শ্ব প্রতিক্রিয়া প্রবর্তন করার সম্ভাবনা রয়েছে। (প্রমাণের জন্য "যাদুর উক্তি" যে সমস্ত সমস্যা তৈরি করেছে তা দেখুন))

সুতরাং আপনি যদি এটি করতে যাচ্ছেন না (স্বয়ংক্রিয়ভাবে সুপারগ্লোবালগুলি ফিল্টার করুন), তবে নিম্নলিখিতগুলি আপনাকে কোনও সুবিধা দেয় না:

$_POST['foo'] = filter($_POST['foo']);

আপনি যখন সহজেই করতে পারেন:

$foo = filter($_POST['foo']);

আমার মনে হয় এটা যে সাইট-ব্যাপী পার্থক্য করতে আরো অনেক কিছু পরিষ্কার $_POSTএবং $_GETকরছে সবসময় অপরিশুদ্ধ, অনির্ভরযোগ্য ডেটা, এবং তারা উচিত না হিসাবে ব্যবহার করা।

ফিল্টারকৃত মানটিকে অন্য ভেরিয়েবলে অনুলিপি করে আপনি দাবি করছেন যে "আমি কী করছি তা আমি বুঝতে পারি ... আমি এই ইনপুটটি ফিল্টার করেছি এবং এটি ব্যবহার করা নিরাপদ।"


ইনপুট দেওয়ার জন্য ধন্যবাদ, আমার ইন্টারনেট প্রায় ২ দিন বাইরে ছিল তাই আমার কারও কাছে উত্তর দেওয়ার সুযোগ পাইনি। উদাহরণস্বরূপ, আমি $ _POST সংশোধন করেছি এবং একটি আপডেট ফাংশনে যাওয়ার জন্য এটি ডেটার অ্যারে হিসাবে ব্যবহার করেছি, ধরে নেওয়া যায় যে আমরা এই ফাংশনে আরও কয়েকটি $ _POST কী পড়ব। আমি একটি নতুন অ্যারে তৈরি করতে পছন্দ করব তবে আমি লোকেরা এর পরিবর্তে এটি করতে দেখেছি, সুতরাং এটিকে "ব্যাড কোড" বলব কিনা তা আমি এখনও কিছুটা নিশ্চিত নই, তবে আমি মনে করি এটি কমপক্ষে সেদিকে ঝুঁকছে। আমি মনে করি যে কোনও সময় আপনি এটি করার প্রয়োজন বোধ করবেন, সবসময় আরও ভাল উপায় আছে।
ওয়েসলি মার্চ

1
@ ওয়েসলি, এটি "খারাপ" হওয়ার প্রাথমিক কারণটি হ'ল এটি আরও বেশি সম্ভাবনা তৈরি করে যে আপনি কিছু ব্যবহারকারীর ডেটা স্যানিটাইজ করতে ভুলে যাবেন। আপনার উদাহরণে, আপনি একটি কী পরিবর্তন করে পুরো অ্যারেটি পাস করুন ray যদি সেই ডেটার কোনওটিতে দূষিত ইনপুট থাকে যা প্রক্রিয়াজাত হয় না? হাতের সাহায্যে সেই নতুন অ্যারে তৈরি $_POSTকরা, এটির মধ্যে কেবল আপনার প্রয়োজনীয় জিনিসগুলি অনুলিপি করা, আপনার সাথে যেতে যেতে স্যানিটাইজিং করা আরও ভাল। এবং অন্যান্য লোকেরা এটি করার বিষয়ে ... ভাল, প্রচুর লোকেরা খুব খারাপ পিএইচপি কোড লেখেন, তবে এটি আপনার পক্ষেও কোনও বাহানা নয়। :)
কনফোর্স

আমি মনে করি কেবলমাত্র স্যানিটাইজিং ডেটা ছাড়াও সুপারগ্লোবাল অপব্যবহারের অন্যান্য অ্যাপ্লিকেশনগুলিকে আমার জোর দেওয়া উচিত ছিল। আমার সম্ভবত এটি পুরোপুরি ছেড়ে দেওয়া উচিত এবং একটি স্পষ্ট প্রশ্ন লেখা উচিত ছিল, লোকেরা বিশেষত সুরক্ষার দিকগুলি বেছে নিতে পছন্দ করে এবং প্রায়শই বাকীগুলি উপেক্ষা করে। কৃতজ্ঞ না বলে, আমি প্রতিক্রিয়াটির সত্যই প্রশংসা করি। আমি একদিন অপেক্ষা করতে যাচ্ছি এবং এটিকে একটি চেক মার্ক দেব, যেমন আপনি কয়েকটি ভাল পয়েন্ট সম্বোধন করেছেন তবে প্রশ্নটি নতুন হওয়ার সময় 3 মিনিটের মধ্যে ভোটদানের দলটি মিস করেছেন :) আবারও ধন্যবাদ!
ওয়েসলি মার্চ

9

আমি সাধারণত পরামর্শ দেব যে আপনার প্রাক-সংজ্ঞায়িত সুপার-গ্লোবালগুলি সংশোধন করা উচিত নয় যাতে স্যানিটাইজ করা ডেটা কী এবং কাঁচা / অবিশ্বস্ত ডেটা কী তা পরিষ্কার হয়ে যায়।

অন্যরা পরামর্শ দিতে পারে যে আপনি যদি অনুরোধ চক্রের শুরুতে সুপারগ্লোবালগুলি পরিষ্কার করেন তবে অন্য কোথাও এগুলি নিয়ে আপনার চিন্তা করার দরকার নেই।

আপনার যখন প্রয়োজন হয় তখন আমি তাদের সাথে সর্বদা মিলে যাতাম:

$id = (int)$_POST['id'];

অথবা সাদৃশ্যপূর্ণ.

অন্যান্য ভেরিয়েবল পরিপ্রেক্ষিতে এটি ভাল অভ্যাস না কোন লিখুন $_GET, $_POST, $_REQUEST, $_SERVERবা $_COOKIE$_SESSIONতবে ভিন্ন কারণ আপনি প্রায়শই অধিবেশনটিতে ডেটা লিখতে চান যা সেশনে বিভিন্ন অনুরোধ জুড়ে থাকে।


2
এই জাতীয় গ্লোবালগুলি প্রয়োজনীয় জিনিসগুলি / পদ্ধতিগুলির সাথে প্রতিস্থাপনের কারণে আরও প্রয়োজনীয় কারণগুলি যখন প্রয়োজন হয় তখন তা পেতে পারে। কেন setcookieঅস্তিত্ব আছে, কিন্তু আমরা কুকিগুলির মাধ্যমে পাই $_COOKIE? এছাড়াও, যেহেতু $_COOKIEকেবলমাত্র বর্তমান অধিবেশনটি শুরু হয় যখন সেট করা থাকে এবং কখনই আপডেট হয় না, তাই আপনার উভয় ক্ষেত্রেই কুকিগুলি পরিবর্তন / সেট করা দরকার যাতে কোডটির পরবর্তী অঞ্চলগুলি আপ টু ডেট তথ্য রাখে।
কেভিন পেনো

ধন্যবাদ জেমস, আমি কিছুক্ষণ অফলাইন ছিলাম তাই আমি সাড়া দিতে পারলাম না। একটি দীর্ঘ গল্প সংক্ষিপ্ত করতে - আমি আপনার সাথে একমত। পোস্ট / পাওয়া / ইত্যাদি লেখার চেয়ে সর্বদা আরও ভাল সমাধান রয়েছে তবে আমি এখনও নিশ্চিত নই যে এটি " কখনও কখনও কখনও করবেন না" হিসাবে এটি কঠোরভাবে খারাপ ধারণা হিসাবে বিবেচিত কিনা । সুতরাং, যদি আমি আবার এই ধরণের কোডটি উপস্থিত করি তবে আপনি কি মনে করেন যে আমার কাছে মড়কির কোডগুলিতে "তাদের কল করার" অধিকার আছে বা কখনও কখনও এটি কোনও চালাক, নিরাপদ উপায়ে ব্যবহার করা যেতে পারে?
ওয়েসলি মার্চ

@ ওয়েসলি যদি এটি "কখনও কখনও করবেন না" তবে সুপারগ্লোবালগুলি সম্ভবত কঠোরভাবে পঠনযোগ্য হবে - তারা তা নয়। আমি কেবলমাত্র এটিকে আপনার অ্যাপ্লিকেশন কোডে সেট করতে বা ওভাররাইট করা খারাপ অভ্যাস বলব - কারণগুলির কারণে।
মিশেল ফিল্ডহাইম

3

আপনি এটি এড়ানো উচিত। কিছু সময় আপনি কিছু স্যানিটাইজ করতে ভুলে গিয়েছিলেন, তবে আপনি বিপজ্জনক ডেটা পুনরুদ্ধার করতে পারেন। স্যানিটাইজ করার সময় যদি আপনি কোনও নতুন কাঠামোতে ডেটা অনুলিপি করেন

  • আপনি কেবল যা পান, যা চান / যা চান তা পান $_POSTনা
  • আপনি সম্ভবত একটি ত্রুটি পাবেন, যদি নতুন তৈরি করা অ্যারেটিতে কিছু কী হারিয়ে যায় বা একেবারে অনুপস্থিত থাকে

অতিরিক্ত অন্যান্য স্ক্রিপ্টগুলি ধরে নিতে পারে, অ্যারেটি ছোঁয়াছে না এবং কৌতূহল প্রকাশ করতে পারে।


2

আমি সুপারগ্লোবাল সংশোধন করার ধারণাটি পছন্দ করি নি কারণ এটি বিভ্রান্তিমূলক। এটি এমন কিছু করার জন্য একটি দ্রুত হ্যাকি উপায় যা প্রায় সম্ভবত আরও ভাল করার উপায় হতে পারে।

$_POSTউদাহরণস্বরূপ, আপনি যদি এর মানটি পরিবর্তন করেন তবে আপনি বলছেন যে সফ্টওয়্যারটি এমন ডেটা পেয়েছিল যা তা নয়।

বাস্তব সমস্যা

বাস্তব জীবনের পরিস্থিতি রয়েছে যেখানে এটি একটি বড় সমস্যা হয়ে দাঁড়িয়েছে:

কল্পনা করুন আপনি একটি দলে কাজ করছেন। একটি আদর্শ বিশ্বে সবাই একই বাক্য গঠন ব্যবহার করে তবে আমরা একটি আদর্শ বিশ্বে বাস করি না। জন বিকাশকারী জন পোস্টিং ডেটা ব্যবহার করে অ্যাক্সেস করতে পছন্দ করেন$_POST । তিনি পোস্ট ওয়ার্সে কিছু পরিবর্তন করেছেন:

$_POST['ranking'] = 2; // John has changed ranking from 1 to 2 for whatever reason

তারপরে আপনার আরেকটি বিকাশকারী ক্রিস রয়েছে, যিনি filter_inputব্যবহারকারীরা যে তথ্য দিয়ে টেম্পার করতে পারে এমন ডেটা প্রসেসিংয়ের সময় সফ্টওয়্যারটি সুরক্ষিত করতে যাওয়ার সাথে ইনপুটযুক্ত (যেমন জিইটি, পোষ্ট, সার্ভার, কুকি) ডেটা অ্যাক্সেস করতে ব্যবহার করতে পছন্দ করেন। সফ্টওয়্যারটির অংশে তার পোস্টের মূল্য পাওয়া দরকার ranking। কোডটির তার অংশটিকোডটির জনের পরে

$ranking = filter_input(INPUT_POST, 'ranking', FILTER_SANITIZE_NUMBER_INT);
// $ranking = 1

উপরের উদাহরণ থেকে, একটি সুপারগ্লোবাল পরিবর্তন করে আপনি পিএইচপি ভেঙে দিয়েছেন। জন $_POST['ranking']যেকোন কারণে জনকে 2 এর মান নির্ধারণ করেছেন , তবে এখন ক্রিস পেয়েছেন 1 এর মান

যখন আমি এটি করার অন্য কোনও উপায় দেখিনি:

আমি এমন একটি প্রকল্পে কাজ করেছি যা ওয়ার্ল্ডপ্রেসকে তার ব্লগ হিসাবে কোনও এডাব্লুএস লোড-ব্যালেন্সারের পিছনে ব্যবহার করেছিল। এটির মান পরিবর্তন করে $_SERVER['remote_address']। এই উদাহরণে, অন্যান্য বিকাশকারীদের নিম্নলিখিতগুলি করা ছাড়া আর কোনও উপায় ছিল না:

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $parts = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
    $_SERVER['REMOTE_ADDR'] = $parts[0];
}

উপসংহার

সুপারগ্লোবালগুলি পরিবর্তনের চেয়ে আরও ভাল উপায় অবশ্যই আছে


1

আমি মনে করি এখানে আসল প্রশ্নটি হল "আপনার থিমটি কেন সংশোধন করা উচিত?"। আমি এটি করার কোনও বৈধ কারণ দেখতে পাচ্ছি না। আপনার যদি কোনও অভিব্যক্তিকে স্যানিটাইজ করতে হয় তবে আপনি একটি স্থানীয় ভেরিয়েবল ব্যবহার করতে চাইতে পারেন…

আপনার কোডটি যথেষ্ট সংক্ষিপ্ত না হলে (বলুন, 50 টিরও কম লম্বা লম্বা), সেই সুপার-গ্লোবাল সংশোধন করা কেবল আপনার কোড বজায় রাখা এবং আন্ডারস্যান্ডের পক্ষে আরও শক্ত করে তুলবে।

যাইহোক, আপনাকে ফাংশনটিতে $ _POST পাস করার দরকার নেই, কারণ এটি একটি সুপারগ্লোবাল অ্যারে যা কোনও ফাংশনের স্থানীয় ক্ষেত্রের মধ্যেও অ্যাক্সেস করা যায়।


3
তবে তার এটা পাস করা উচিত । অন্যথায় এটি পরীক্ষা করা খুব কঠিন এবং কোনও মান (এমনকি
কুশলী

ঠিক আছে, এটি তার পদ্ধতি কী করে তার উপর নির্ভর করে। যদি এটি কেবল _P _POST অ্যারেতে যা আছে তা পার্স করার জন্য তৈরি করা হয়, তবে তাকে এটি পাস করার দরকার নেই। অবশ্যই, যদি এটি আপনার চেয়ে ঠিক একটি সাধারণ / বিমূর্ত উদ্দেশ্য পরিবেশন করে।

2
@ থমাস, আমি এখানে রাজার সাথে একমত এমনকি যদি তারা বিশ্বব্যাপী হয় তবে আপনার অন্যান্য স্কোপের অভ্যন্তরে বৈশ্বিক কিছু ব্যবহার করা উচিত নয় কারণ এটি শক্ত দম্পতির কারণ হয় (যার কারণে ফাংশনটি পুনরায় ব্যবহার করা যায় না)। আপনার উদাহরণস্বরূপ, যদি ফাংশনটি ডেটা স্যানিটাইজ করা হয় তবে কেন এটি কেবল $_POSTডেটা স্যানিটাইজ করে? প্রবেশের $_POSTফলে ফাংশনটি কোনও ডেটা স্যানিটাইজ করে।
কেভিন পেনো

0

শুরুতে সুপারগ্লোবালগুলি সংশোধন করার কোনও কারণ নেই বলে এই প্রশ্নের উত্তর দেওয়ার পরে, আমি যখন সিদ্ধান্ত নেওয়ার সিদ্ধান্ত নিয়েছি তখন একটি উত্তর দিয়ে এই উত্তরটি সম্পাদনা করছি।

আমি বর্তমানে একটি ইউআরএল পুনর্লিখনের ডাটাবেস টেবিলের সাথে কাজ করছি যার অধীনে requestকলামটি ব্যবহারকারীকে তার সংশ্লিষ্ট targetকলামে নির্দেশ করে ।

উদাহরণস্বরূপ, একটি requestহতে পারে blog/title-hereএবং এটি targetহতে পারে blog.php?id=1

যেহেতু ভেরিয়েবলের blog.phpপ্রত্যাশা $_GET, এবং আমি পরিবর্তন করতে চাই না header("Location:"), তাই আমি এই জাতীয় কিছু করতে থাকি:

$uri    = explode('?', $uri_request)[0];
$params = explode('?', $uri_request)[1];
parse_str($params, $_GET);

এটি কলাম $_GETদ্বারা পাস করা উদ্দেশ্যযুক্ত পরামিতিগুলি সহ একটি অ্যারে তৈরি করে target

শেষ পর্যন্ত, সুপারগ্লোবালগুলি সংশোধন করার বিরুদ্ধে দৃ strongly়ভাবে পরামর্শ দেব যদি না আপনি একেবারে না থাকেন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.