ฉันจะค้นหาวิธีสาธารณะที่มีอยู่ได้อย่างไร


9

ฉันพบว่าปัญหาที่ใหญ่ที่สุดในการทำงานกับ Drupal 8 คือฉันไม่สามารถรับข้อมูลที่ต้องการได้ Drupal 8 ต้องการให้ฉันใช้วิธีสาธารณะแทนที่จะเจาะลึกวัตถุด้วยตนเอง ปัญหาคือฉันไม่สามารถหาวิธีที่สอดคล้องกันในการรับรายการวิธีการที่ใช้ได้! (พวกเขามีอยู่อย่างน่าอัศจรรย์และฉันรู้สึกว่าฉันควรจะรู้เกี่ยวกับพวกเขา)

สำหรับตัวอย่างนี้สมมติว่าฉันมีประเภทเนื้อหาที่มีฟิลด์วิดีโอ ฉันต้องได้รับ URL ดิบของไฟล์วิดีโอในฟิลด์นั้น

ดังนั้นฉันจะเริ่มต้นด้วย node id ($ nid) และอย่างใดฉันต้องคิดวิธีการโหลดโหนด สิ่งนี้ไม่เลวร้ายนักเพราะมีตัวอย่างมากมาย $node = \Drupal\node\Entity\Node::load($nid);ดังนั้นผมจึงทำสิ่งที่ชอบ

จนถึงตอนนี้ดีมาก จากนั้นฉันต้องรับค่าฟิลด์วิดีโอของฉัน (field_main_video) สิ่งนี้ทำให้ฉันตลอดไปที่จะคิดออกเพราะมีเอกสารที่ขัดแย้งรอบ 'สุทธิ ในที่สุดฉันก็พบว่าฉันต้องทำอะไรแบบนี้ (เพราะมันเป็นรายการที่มีหลายค่า):

$video = \Drupal\node\Entity\Node::load($nid)->field_main_video->getValue();

... จากนั้นวนรอบอาร์เรย์เป็นต้นการใช้ kint ไม่ได้ช่วยฉันในการค้นหาสิ่งนี้เช่นกัน เพราะตัวอย่างเช่นถ้าฉันkint($node)และดูวิธีการฉันไม่เห็น getValue () เป็นรายการที่มี ยังคงไม่น่ากลัวเพราะมีตัวอย่างเพียงพอที่จะคิดออก

ในขณะที่ฉันไปให้ลึกกว่านั้นสิ่งที่ฉันไม่รู้ (นี่คือส่วนสำคัญ) ก็คือแทนที่จะได้รับรหัสเอนทิตีของฟิลด์วิดีโอแล้วโหลดเอนทิตีแล้วค้นหาเอนทิตี "uri" ในเอนทิตี้ ฯลฯ (เช่น ฉันจะเป็น D7): มีวิธีที่ทำให้ฉันได้รับ URI ทั้งหมดในรหัสบรรทัดเดียวกันนี้!

$url = \Drupal\node\Entity\Node::load($nid)->field_main_video->entity->getFileUri();

แต่ฉันจะรู้ได้อย่างไรว่า getFileUri () นี้มีอยู่จริง? ฉันบังเอิญพบมันในโพสต์บล็อก สิ่งนี้ทำให้การได้รับ URI ง่ายกว่าใน D7 ... แต่ถ้าคุณรู้ (อย่างน่าอัศจรรย์) วิธีการที่มีอยู่สำหรับ 'ระดับ' ของแต่ละวัตถุ

ในท้ายที่สุดจากตัวอย่างนี้ฉันถามว่า: คุณจะหาวิธีการสาธารณะทั้งหมดสำหรับแต่ละระดับของวัตถุในวิธีที่ง่ายต่อการอ่านและทำความเข้าใจอย่างไร โปรดทราบว่าดูเหมือนว่าควรมี drupal-centric (เช่นโมดูล devel) ในการทำสิ่งนี้แทนที่จะค้นหาด้วยตนเอง api.drupal.org หรือใช้บางสิ่งบางอย่างที่เฉพาะเจาะจงของ IDE?


1
เอกสารอย่างเป็นทางการอยู่ที่ api.drupal.org เมื่อคุณเข้าใจคลาสของวัตถุที่คุณกำลังจัดการคุณจะได้รับวิธีการทั้งหมดรวมถึงวัตถุที่สืบทอดมา
— kiamlaluno

1
... แต่แทนที่จะค้นหาทุกอย่างใน api.drupal.org แน่นอนว่ามีวิธีใน php / devel ในการถ่ายโอนวิธีการที่มีอยู่ไปยังหน้าจอเมื่อมีคำสั่ง?
— Bobby

คำตอบ:


14

เอนทิตีเนื้อหาแตกต่างจากสิ่งอื่น ๆ ส่วนใหญ่ซึ่งมักจะไม่มีวิธีการและอินเทอร์เฟซที่เหมาะสมอย่างน้อยก็ไม่ใช่ฟิลด์ที่กำหนดค่าได้

ในกรณีของเอนทิตีและฟิลด์เนื้อหาเมธอดสาธารณะไม่ใช่สิ่งที่คุณต้องการทราบอย่างแท้จริงสิ่งที่คุณต้องการคือรู้เกี่ยวกับฟิลด์และคุณสมบัติ และเมื่อคุณได้รับเอนทิตีอีกครั้งผ่านการอ้างอิงแล้ววิธีการที่สำคัญ

สำหรับภาพรวมฉันมักจะอ้างถึงEntity API Cheat Sheetที่ยอดเยี่ยมเสมอ

เอนทิตีเนื้อหามีโครงสร้างแบบคงที่เอนทิตี> ฟิลด์ (FieldItemList)> FieldItem -> Property คุณสมบัติเป็นแบบเกลาหรือการอ้างอิงถึงสิ่งอื่นเช่นเอนทิตีอื่น, วัตถุภาษา, วัตถุวันที่, ...

สำหรับตัวอย่างที่ระบุบางตัวอย่างตัวอย่างที่มีประโยชน์:

// List of fields that an entity has, the field definitions also have a lot of information like the type.
array_keys($entity->getFieldDefinitions())

// Use get() instead of the magic __get() on the entity level then you at least get some type hints.
$entity->get('field_name').

// Get the list of properties a certain field has, use array_keys() again for just the names, but the definitions also have the type and if it's computed or not.
$entity->getFieldDefinition('field_name')->getFieldStorageDefinition()->getPropertyDefinitions()

// Most field types have value property, but e.g. entity references have target_id and the computed entity. as you found. File and Image fields have additional properties like title/alt/description.
$entity->get('field_name')->value
$entity->get('field_name')->target_id
$entity->get('field_name')->entity

// Note that get('value') is not the same as ->value on the field item level, get() returns a typed data object, get('value')->getValue() is the same as ->value.

// When not specified, the delta 0 is assumed (all fields are a list internally, even something like the node id), you can use array access or the delta to access another delta, make sure it exists.
$entity->get('field_name')[1]->value
$entity->get('field_name')->get(1)->value

// When you have an entity reference, you can get the entity type and class like this:
$entity->get('field_name')->entity->getEntityTypeId()
$entity->get('field_name')->entity->getEntityType()->getClass()
// or 
get_class($entity->get('field_name')->entity)

// From there you can look up the interface and type hint against that, to a) make sure you have a valid, loadable reference and get type hints in an IDE:
$file = $entity->get('field_name')->entity;
if ($file instanceof \Drupal\file\FileInterface) {
  $file->getFileUri();
}

ดี! นี่จะใช้เวลาสักครู่ในการย่อย แต่ฉันเอนตัวไปสู่คำตอบที่ได้รับการยอมรับ ขอบคุณ! มันไม่ได้ตอบคำถามอย่างแน่นอน แต่นั่นเป็นเพราะคำถามของฉันและตัวอย่างของฉันคือการถาม 2 สิ่งที่แตกต่างกัน ขอบคุณ!
— Bobby

1
@Berdir นี่เป็นรายการตัวอย่างที่น่ากลัว ฉันแค่ google เพื่อรับข้อมูลข้อมูลใด ๆ และไม่มีอะไรใกล้เคียงกับสิ่งนี้ คำตอบที่ดีวัสดุหนังสือ
— Marko Blazekovic

4

ไม่แน่ใจว่าจะตอบคำถามของคุณได้อย่างสมบูรณ์ แต่สิ่งที่ช่วยฉันได้มากคือการใช้คุณสมบัติไดอะแกรมใน PhpStorm

ตัวอย่างเช่นแสดงลำดับชั้น ป้อนคำอธิบายรูปภาพที่นี่

คุณมีตัวเลือกเพื่อแสดงชื่อวิธีการ

ป้อนคำอธิบายรูปภาพที่นี่

ฉันหวังว่านี่จะช่วยคุณได้


คุณยังสามารถเปิดคลาสด้วยคำสั่ง + คลิกจากนั้นคำสั่ง + 7 หรือคลิกแท็บโครงสร้างเพื่อดูโครงสร้างคลาส (ซึ่งมุมมองไดเรกทอรีโครงการของคุณจะเป็น) เพื่อสแกนข้อมูลเดียวกันโดยไม่ต้องเปิด UML
— Kevin

ฉันไม่ได้ใช้ phpstorm แต่เป็นการดีที่จะทราบสำหรับการอ้างอิงในอนาคต ฉันกำลังมองหาวิธีในการทำเช่นนี้โดยใช้ devel หรือบางสิ่งบางอย่าง drupal-centric ต้องสร้างบางสิ่งในที่ใดบ้าง?
— Bobby

ฉันขอโทษที่ต้องบอกว่า แต่ฉันไม่คิดว่าตอนนี้คุณสามารถคนจรจัดกับ API ได้อย่างมีประสิทธิภาพโดยไม่ต้องใช้ IDE นี้
— Oleg Videnov

NetBeans ยังมีไดอะแกรมลำดับชั้นของ PHP อีกด้วย อาจจะไม่เจ๋งนัก แต่ NetBeans เป็นซอฟต์แวร์เสรี (PHP Storm ปิดแหล่งที่มาและราคาแพง IMHO) และคุณสามารถดาวน์โหลดได้ฟรี
— sanzante

IDE ที่มีค่าเกลือสามารถทำได้ BTW PHPS รูปแบบไม่แพงถ้าคุณใช้สิ่งที่มีให้ คุณสามารถใช้รุ่น EAP ฟรีและหากคุณทำงานในโครงการโอเพนซอร์ส (โมดูลหรือธีม Drupal) JetBrains จะให้สิทธิ์ใช้งานฟรีแก่คุณ ไม่ใช่การสนทนาที่นี่แม้ว่า
— Kevin

4

ดีฉันพบว่าตัวเองใช้บ่อยมากรวมกันของvar_dump(get_class_methods($object))การมีรายการของวิธีการที่ใช้ได้สำหรับชั้นเรียนที่กำหนด

ฉันยังดูบ่อยapi.drupal.orgสำหรับรายละเอียดเพิ่มเติม


2
ดูเหมือนว่าคำตอบจะเกี่ยวข้องกับสิ่งที่ฉันกำลังมองหามากที่สุด ขอบคุณ!
— Bobby

0

คุณสนิทแล้ว

อันดับแรกให้ดูที่คำจำกัดความของวิธีการ: https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/function/File%3A%3AgetFileUri/8.2.x

จากที่นี่เราสามารถเห็นชั้นนี้เป็นส่วนหนึ่งและมีการเชื่อมโยงไป:

Class

File
Defines the file entity class.

การคลิกผ่านจะนำเราไปที่: https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/class/File/8.2.x

ใน IDE ของคุณคุณสามารถค้นหา\Drupal\file\Entity\Fileชั้นเรียนได้ด้วย วิธีหนึ่งที่จะแน่ใจได้ว่านี่เป็นคลาสที่ถูกต้องคือการดูหมายเหตุประกอบ:

@ContentEntityType(
  id = "file",
  label = @Translation("File"),
  handlers = {
    "storage" = "Drupal\file\FileStorage",
    "storage_schema" = "Drupal\file\FileStorageSchema",
    "access" = "Drupal\file\FileAccessControlHandler",
    "views_data" = "Drupal\file\FileViewsData",
  },
  base_table = "file_managed",
  entity_keys = {
    "id" = "fid",
    "label" = "filename",
    "langcode" = "langcode",
    "uuid" = "uuid"
  }
) 

แจ้งให้ทราบล่วงหน้าid- fileมันเป็น สันนิษฐานว่าหากการดีบักคุณสามารถดูเนื้อหาของfield_main_video->entityและคุณจะเห็น ID นี้ที่ไหนสักแห่ง จากนั้นคุณเพียงค้นหาใน IDE ของคุณ อย่างไรก็ตามโดยปกติแล้วมีใครรู้มากพอเกี่ยวกับประเภทเอนทิตีหนึ่งที่ใช้ในการเดาทางไปยังคลาสที่ถูกต้อง

เฉพาะในกรณีนี้ผมยังไม่ทราบว่าFileเป็นอาจจะเป็นระดับที่ขยายContentEntityBaseเพราะมันมากขึ้นเช่นเนื้อหาของฐานข้อมูล (เป็นนิติบุคคลเนื้อหา) มากกว่าการกำหนดค่า (การกำหนดค่านิติบุคคล) ดังนั้นเมื่อฉันเห็นสมมติฐานของฉันยืนยันนั่นจะช่วยให้ฉันรู้ว่าฉันได้พบชั้นเรียนที่เหมาะสม

ดังนั้นโดยย่อ: IDE ของคุณdebug()ข้อความเชิงกลยุทธ์และการคาดเดาบางอย่างเป็นวิธีที่ดีที่สุดในการค้นหา Drupal 8

บันทึกการเปลี่ยนแปลง PS สามารถเป็นประโยชน์ได้เช่นกัน พวกเขาอยู่ที่https://www.drupal.org/list-changes/drupal


ฉันใช้ปัญหาของ OP คือสิ่งที่ตรงกันข้าม: การรู้ว่าวิธีการเรียนแบบสาธารณะใดที่ชั้น / อุปกรณ์ใช้ได้
— kiamlaluno

ใช่ฉันอาจต้องอ่านมันอีกครั้ง แต่ฉันไม่คิดว่ามันเป็นสิ่งที่ฉันกำลังมองหา ฉันพยายามหาว่า getFileUri () ยังคงมีอยู่ตั้งแต่แรก!
— Bobby

@Bobby ไฟล์เป็นประเภทเอนทิตีดังนั้นคุณเพียงแค่ดูที่แหล่งที่มาซึ่งคุณจะพบวิธีการที่คุณได้รับการจดทะเบียนและจัดทำเอกสารอย่างครบถ้วน เป็นเพียงว่าคุณไม่ทราบว่าไฟล์เป็นประเภทเอนทิตีหรือไม่? หรือว่าคุณไม่ทราบว่าการประชุมสำหรับการค้นหาประเภทเอนทิตีในรหัส? หรืออย่างอื่นขึ้นโซ่? มีหลายเลเยอร์ของสิ่งที่เป็นนามธรรมสำหรับ D8 มันเป็นวิธีที่เข้าใจง่ายดังนั้นจึงมีความรู้ "ฐาน" จำนวนมากที่คุณต้องการก่อนที่จะเจาะรหัส
— Clive

0

คุณสามารถใช้ฟังก์ชัน PHP get_class_methods ตัวอย่างด้านล่างนี้ผู้ใช้อัพโหลดไฟล์:

$image = $form_state->getValue('image_field_name_from_form');
$file = File::load( $image[0] );
$file->setPermanent();
$file->save();

$methods = [];
foreach (get_class_methods($file) as $method) {
        $methods[] = $method;
}
print_r($methods);

สิ่งนี้จะเพิ่มวิธีการทั้งหมดที่มีให้กับวัตถุ $ file ลงในอาร์เรย์ $ methods ซึ่งคุณสามารถพิมพ์แล้วดูวิธีการทั้งหมดที่มีอยู่ สิ่งนี้ใช้ได้สำหรับวัตถุใด ๆ ใน PHP ไม่ใช่แค่ Drupal

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.