মতবাদ 2 এ প্রক্সি কী?


112

আমি সবেমাত্র সমস্ত ডক্ট্রিন 2 ডকুমেন্টেশন পড়া শেষ করেছি, আমি নিজস্ব স্যান্ডবক্স শুরু করেছি, বেশিরভাগ প্রিন্সিপাল বুঝতে পেরেছি, কিন্তু এখনও একটি প্রশ্ন আছে এবং আমি ডকটিতে কোনও সম্পূর্ণ ব্যাখ্যা খুঁজে পাইনি।

  1. Proxyক্লাস কি ?
  2. সত্ত্বাগুলির উপরে কখন সেগুলি ব্যবহার করব?

যতদূর আমি বুঝতে পেরেছি, প্রক্সি ক্লাসগুলি আপনাকে আপনার সত্তাগুলিতে কিছু অন্যান্য বৈশিষ্ট্য যুক্ত করতে একটি স্তর যুক্ত করে, তবে কেন সত্তা শ্রেণিতে তাদের পদ্ধতিগুলি প্রয়োগ করার পরিবর্তে প্রক্সি ব্যবহার করবেন?

উত্তর:


160

হালনাগাদ

এই উত্তরে প্রক্সি অবজেক্ট এবং আংশিক বস্তুর মধ্যে পার্থক্য সম্পর্কে ভুল তথ্য রয়েছে। আরও তথ্যের জন্য @ কনট্রোলফ্রেকের উত্তর দেখুন: https://stackoverflow.com/a/17787070/252591


যখনই আপনার কোয়েরি সত্তা তৈরির জন্য প্রয়োজনীয় সমস্ত ডেটা ফেরত দেয় না তখনই প্রক্সি অবজেক্টগুলি ব্যবহার করা হয়। নিম্নলিখিত দৃশ্যের কল্পনা করুন:

@Entity
class User {
     @Column protected $id;
     @Column protected $username;
     @Column protected $firstname;
     @Column protected $lastname;

     // bunch of setters/getters here
}

DQL query:

SELECT u.id, u.username FROM Entity\User u WHERE u.id = :id

আপনি দেখতে পাচ্ছেন যে এই কোয়েরিটি ফিরে আসে না firstnameএবং lastnameবৈশিষ্ট্যগুলিও তাই আপনি Userঅবজেক্ট তৈরি করতে পারবেন না । অসম্পূর্ণ সত্তা তৈরি অপ্রত্যাশিত ত্রুটি হতে পারে।

এই কারণেই মতবাদ UserProxyঅলস লোডিংকে সমর্থন করে এমন একটি বস্তু তৈরি করবে । যখন আপনি firstnameসম্পত্তি অ্যাক্সেস করার চেষ্টা করবেন (যা লোড হয় না) এটি প্রথমে ডাটাবেস থেকে সেই মানটি লোড করবে।


মানে আমি কেন প্রক্সি ব্যবহার করব?

আপনার কোডটি সর্বদা এমনভাবে লেখা উচিত যেন আপনি প্রক্সি অবজেক্টগুলি ব্যবহার করেন নি। এগুলিকে মতবাদ দ্বারা ব্যবহৃত অভ্যন্তরীণ বস্তু হিসাবে বিবেচনা করা যেতে পারে।

অলস লোডিংটি এন্টিটিতেই প্রয়োগ করা যায় না কেন?

প্রযুক্তিগতভাবে এটি হতে পারে তবে কিছু এলোমেলো প্রক্সি বস্তুর শ্রেণিতে একবার দেখুন। এটি নোংরা কোড পূর্ণ, উঘ। আপনার সত্তা একটি পরিষ্কার কোড আছে খুব ভাল।

আপনি আমাকে একটি ব্যবহারের কেস সরবরাহ করতে পারেন?

আপনি সর্বশেষ 25 টি নিবন্ধের তালিকা প্রদর্শন করছেন এবং আপনি প্রথমটির একটি বিবরণ প্রদর্শন করতে চান। তাদের প্রত্যেকটিতে একটি বিশাল পরিমাণে পাঠ্য রয়েছে, সুতরাং সেই সমস্ত ডেটা আনা মেমোরির অপচয় হবে। এজন্য আপনি অপ্রয়োজনীয় ডেটা আনছেন না।

SELECT a.title, a.createdAt
FROM Entity\Article a
ORDER BY a.createdAt DESC
LIMIT 25

$isFirst = true;
foreach ($articles as $article) {
    echo $article->getTitle();
    echo $article->getCreatedAt();

    if ($isFirst) {
        echo $article->getContent(); // Article::content is not loaded so it is transparently loaded 
                                     // for this single article.

        $isFirst = false;
    }
}

আপনার উত্তরের জন্য ধন্যবাদ, এটি আংশিক অবজেক্টের সাথে আলাদা কী? মানে আমি কেন প্রক্সি ব্যবহার করব? অলস লোডিংটি এন্টিটিতেই প্রয়োগ করা যায় না কেন? আপনি আমাকে একটি ব্যবহারের কেস সরবরাহ করতে পারেন?
জার্মি

1
আংশিক বস্তু এবং প্রক্সি অবজেক্ট একই জিনিস - এগুলি প্রতিশব্দ হিসাবে বিবেচনা করা যেতে পারে। বাকি প্রশ্নগুলির জন্য আমার আপডেট হওয়া উত্তরগুলি পরীক্ষা করে দেখুন।
ক্রুজিন

1
আমি বুঝতে পারছি না কেন মতবাদ কেন এটির অর্ধেক বৈশিষ্ট্য থাকলে অবজেক্ট তৈরি করতে পারে না। পিএইচপি-তে আমি সমস্ত সম্পত্তি নির্ধারণ না করেও আমি একটি অবজেক্ট তৈরি করতে সক্ষম।
স্যান্ডার্স

1
এটি সম্পূর্ণ দুর্দান্ত উত্তর এবং ডকুমেন্টেশনে থাকা উচিত।
জিম্বো

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

81

প্রক্সি

একটি ডক্ট্রাইন প্রক্সি কেবল একটি মোড়ক যা এটির জন্য অলস লোডিং সরবরাহ করতে সত্তা শ্রেণি প্রসারিত করে।

ডিফল্টরূপে, আপনি যখন অন্য সত্তার সাথে সম্পর্কিত একটি সত্তার জন্য সত্তা পরিচালককে জিজ্ঞাসা করেন, তখন সংশ্লিষ্ট সত্তা ডাটাবেস থেকে লোড হবে না, তবে প্রক্সি অবজেক্টে আবৃত হবে। যখন আপনার অ্যাপ্লিকেশন তখন কোনও সম্পত্তির জন্য অনুরোধ করে বা এই প্রক্সাইড সত্তার কোনও পদ্ধতিতে কল করে তখন ডক্ট্রাইন ডাটাবেস থেকে সত্তাটি লোড করে দেবে (আপনি যখন আইডির অনুরোধ করবেন না, যা সর্বদা প্রক্সিটির সাথে পরিচিত)।

প্রক্সিটি আপনার সত্তা শ্রেণীর প্রসারিত করে এই কারণে এটি আপনার আবেদনে সম্পূর্ণ স্বচ্ছ হয় happens

মতবাদটি ডিফল্টভাবে হাইড্রেট সংঘগুলি অলস লোড প্রক্সি হিসাবে সংঘবদ্ধ করে যদি আপনি JOINসেগুলি আপনার ক্যোয়ারিতে না রাখেন বা আনতে মোড সেট করেন না EAGER


এখন আমার এটি অবশ্যই যুক্ত করা উচিত কারণ আমার কাছে সর্বত্র মন্তব্য করার মতো খ্যাতি নেই:

দুর্ভাগ্যক্রমে, ক্রোজিনের উত্তরে ভুল তথ্য রয়েছে।

আপনি যদি একটি ডিকিউএল কোয়েরি কার্যকর করেন

SELECT u.id, u.username FROM Entity\User u WHERE u.id = :id

আপনি কোনও (প্রক্সড) সত্তা বস্তু পাবেন না, তবে একটি সহযোগী অ্যারে পাবেন। সুতরাং কোনও অতিরিক্ত বৈশিষ্ট্য লোড করা সম্ভব নয়।

এটি মাথায় রেখে, একটি সিদ্ধান্তে পৌঁছেছে যে ব্যবহারের ক্ষেত্রে উদাহরণটি কাজ করবে না। $articleঅবজেক্ট হিসাবে অ্যাক্সেস করার জন্য ডিকিউএলকে এই জাতীয় কিছুতে পরিবর্তন করতে হবে :

SELECT a FROM Entity\Article a ORDER BY a.createdAt DESC LIMIT 25

এবং সমস্ত 25 সত্তার getContent()সামগ্রীর বৈশিষ্ট্য লোড না করার জন্য সম্পত্তিটি ফেরত দেওয়া সম্পত্তি হতে হবে


আংশিক বিষয়

আপনি যদি সংস্থাগুলি নয় এমন সত্তা বৈশিষ্ট্যগুলি আংশিকভাবে লোড করতে চান তবে আপনাকে এই মতবাদটি স্পষ্টভাবে বলতে হবে:

SELECT partial u.{id, username} FROM Entity\User u WHERE u.id = :id

এটি আপনাকে আংশিকভাবে লোড করা সত্তা বস্তু দেয়।

তবে সাবধান হোন যে আংশিক জিনিসগুলি প্রক্সি নয় ! অলস লোডিং তাদের জন্য প্রযোজ্য নয়। সুতরাং, আংশিক জিনিস ব্যবহার করা সাধারণত বিপজ্জনক এবং এড়ানো উচিত should আরও পড়ুন: আংশিক বিষয় - মতবাদ 2 ওআরএম 2 ডকুমেন্টেশন


1
ধন্যবাদ, এটি গ্রহণযোগ্য উত্তরের চেয়ে মতবাদ কীভাবে প্রক্সি এবং আংশিক অবজেক্ট ব্যবহার করে সে সম্পর্কে আরও অনেক বিশদ সরবরাহ করে! এবং ডক্সের উল্লেখটিও সহায়ক।
শিম বিন

1
এছাড়াও রেফারেন্সের জন্য, এখানে প্রক্সি সম্পর্কে ডক্সের অধ্যায় বস্তু আছে: doctrine-orm.readthedocs.org/en/latest/reference/...
শন বিন

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