😅Sử dụng namespace & Autoload trong Plugin sử dụng namespace ở file functions (ok)

https://code.tutsplus.com/vi/tutorials/using-namespaces-and-autoloading-in-wordpress-plugins-4--cms-27342

Tạm thời ta không dùng chức năng trong file này nữa. C:\xampp824\htdocs\testcom\wp-content\plugins\tutsplus-namespace-demo\tutsplus-namespace-demo.php

Sử dụng nó trong C:\xampp824\htdocs\testcom\wp-content\themes\twentytwentyone\functions.php

Chức năng vẫn hoạt động bình thường

Tham khỏa: https://www.smashingmagazine.com/2015/05/how-to-use-autoloading-and-a-plugin-container-in-wordpress-plugins/

https://makeitwork.press/wordpress-autoload-classes-php-composer/

Ví dụ hoàn chỉnh:

C:\xampp\htdocs\test\wp-content\plugins\tutsplus-namespace-demo\tutsplus-namespace-demo.php

<?php
/**
 * The plugin bootstrap file
 *
 * This file is read by WordPress to generate the plugin information in the
 * plugin admin area. This file also includes all of the dependencies used by
 * the plugin, registers the activation and deactivation functions, and defines
 * a function that starts the plugin.
 *
 * @link              https://.tutsplus.com/tutorials/using-namespaces-and-autoloading-in-wordpress-plugins-part-1
 * @since             0.1.0
 * @package           tutsplus_namespace_demo
 *
 * @wordpress-plugin
 * Plugin Name:       Tuts+ Namespace Lionel
 * Plugin URI:        http://.tutsplus.com/tutorials/using-namespaces-and-autoloading-in-wordpress-plugins-part-1
 * Description:       Learn how to use Namespaces and Autoloading in WordPress.
 * Version:           0.2.0
 * Author:            Tom McFarlin
 * Author URI:        https://tommcfarlin.com/
 * License:           GPL-2.0+
 * License URI:       http://www.gnu.org/licenses/gpl-2.0.txt
 */
use Tutsplus_Namespace_Demo\Admin;
use Tutsplus_Namespace_Demo\Admin\Util;
// If this file is accessed directory, then abort.
if (!defined('WPINC')) {
  die;
}
// Include the autoloader so we can dynamically include the rest of the classes.
require_once trailingslashit(dirname(__FILE__)) . 'inc/autoload.php';
add_action('plugins_loaded', 'tutsplus_namespace_demo');
/**
 * Starts the plugin by initializing the meta box, its display, and then
 * sets the plugin in motion.
 */
function tutsplus_namespace_demo() {
  $meta_box = new Admin\Meta_Box(new Admin\Meta_Box_Display(new Util\Question_Reader()));
  $css_loader = new Util\CSS_Loader();
  $css_loader->init();
  $meta_box->init();
}

C:\xampp\htdocs\test\wp-content\plugins\tutsplus-namespace-demo\inc\autoload.php

<?php
/**
 * Dynamically loads the class attempting to be instantiated elsewhere in the
 * plugin.
 *
 * @package Tutsplus_Namespace_Demo\Inc
 */
spl_autoload_register('tutsplus_namespace_demo_autoload');
/**
 * Dynamically loads the class attempting to be instantiated elsewhere in the
 * plugin by looking at the $class_name parameter being passed as an argument.
 *
 * The argument should be in the form: TutsPlus_Namespace_Demo\Namespace. The
 * function will then break the fully-qualified class name into its pieces and
 * will then build a file to the path based on the namespace.
 *
 * The namespaces in this plugin map to the paths in the directory structure.
 *
 * @param string $class_name The fully-qualified name of the class to load.
 */
function tutsplus_namespace_demo_autoload($class_name) {
  // If the specified $class_name does not include our namespace, duck out.
  if (false === strpos($class_name, 'Tutsplus_Namespace_Demo')) {
    return;
  }
  // Split the class name into an array to read the namespace and class.
  $file_parts = explode('\\', $class_name);
  // Do a reverse loop through $file_parts to build the path to the file.
  $namespace = '';
  for ($i = count($file_parts) - 1; $i > 0; $i--) {
    // Read the current component of the file part.
    $current = strtolower($file_parts[$i]);
    $current = str_ireplace('_', '-', $current);
    // If we're at the first entry, then we're at the filename.
    if (count($file_parts) - 1 === $i) {
      /* If 'interface' is contained in the parts of the file name, then
       * define the $file_name differently so that it's properly loaded.
       * Otherwise, just set the $file_name equal to that of the class
       * filename structure.
       */
      if (strpos(strtolower($file_parts[count($file_parts) - 1]), 'interface')) {
        // Grab the name of the interface from its qualified name.
        $interface_name = explode('_', $file_parts[count($file_parts) - 1]);
        $interface_name = $interface_name[0];
        $file_name      = "interface-$interface_name.php";
      } else {
        $file_name = "class-$current.php";
      }
    } else {
      $namespace = '/' . $current . $namespace;
    }
  }
  // Now build a path to the file using mapping to the file location.
  $filepath = trailingslashit(dirname(dirname(__FILE__)) . $namespace);
  $filepath .= $file_name;
  // If the file exists in the specified path, then include it.
  if (file_exists($filepath)) {
    include_once $filepath;
  } else {
    wp_die(esc_html("The file attempting to be loaded at $filepath does not exist."));
  }
}

C:\xampp\htdocs\test\wp-content\plugins\tutsplus-namespace-demo\admin\class-meta-box.php

<?php
/**
 * Represents a meta box to be displayed within the 'Add New Post' page.
 */
namespace Tutsplus_Namespace_Demo\Admin;
class Meta_Box {
  /**
   * A reference to the Meta Box Display.
   *
   * @access private
   * @var    Meta_Box_Display
   */
  private $display;
  /**
   * Initializes this class by setting its display property equal to that of
   * the incoming object.
   *
   * @param Meta_Box_Display $display Displays the contents of this meta box.
   */
  public function __construct($display) {
    $this->display = $display;
  }
  /**
   * Registers this meta box with WordPress.
   *
   * Defines a meta box that will render inspirational questions at the top
   * of the sidebar of the 'Add New Post' page in order to help prompt
   * bloggers with something to write about when they begin drafting a post.
   */
  public function init() {
    add_action( 'add_meta_boxes', array( $this, 'wpdocs_register_meta_boxes' ) );
  }
  public function wpdocs_register_meta_boxes() {
    add_meta_box('tutsplus-post-questions','Inspiration Questions',array($this->display, 'render'),'post','side','high');
  }
}

C:\xampp\htdocs\test\wp-content\plugins\tutsplus-namespace-demo\admin\class-meta-box-display.php

<?php
/**
 * Defines the functionality required to render the content within the Meta Box
 * to which this display belongs.
 */
namespace Tutsplus_Namespace_Demo\Admin;
class Meta_Box_Display {
  /**
   * A reference to the object responsible for retrieving a question to display.
   *
   * @access private
   * @var    Question_Reader $question_reader
   */
  private $question_reader;
  /**
   * Initializes the class by setting the question reader property.
   *
   * @param Question_Reader $question_reader The object for retrieving a question.
   */
  public function __construct($question_reader) {
    $this->question_reader = $question_reader;
  }
  /**
   * Sanitizes the incoming markup to the user so that
   *
   * @access private
   * @param  string $html The markup to render in the meta box.
   * @return string       Sanitized markup to display to the user.
   */
  private function sanitized_html($html) {
    $allowed_html = array(
      'p' => array("class"=>array('aaaaaa'))
    );
    return wp_kses($html, $allowed_html);
  }
  /**
   * Renders a single string in the context of the meta box to which this
   * Display belongs.
   */
  /**
   * Renders a single string in the context of the meta box to which this
   * Display belongs.
   */
  public function render() {
    $file     = dirname(__FILE__) . '/data/questions.txt';
    $question = $this->question_reader->get_question_from_file($file);
    $html = "<p class='aaaaaa2' id='tutsplus-author-prompt'>$question</p>";
    echo $this->sanitized_html($html);
  }
}

C:\xampp\htdocs\test\wp-content\plugins\tutsplus-namespace-demo\admin\util\interface-assets.php

<?php
namespace Tutsplus_Namespace_Demo\Admin\Util;
interface Assets_Interface {
  public function init();
  public function enqueue();
}

C:\xampp\htdocs\test\wp-content\plugins\tutsplus-namespace-demo\admin\util\class-css-loader.php

<?php
/**
 * Provides a consistent way to enqueue all administrative-related stylesheets.
 */
namespace Tutsplus_Namespace_Demo\Admin\Util;
class CSS_Loader implements Assets_Interface {
  /**
   * Registers the 'enqueue' function with the proper WordPress hook for
   * registering stylesheets.
   */
  public function init() {
    add_action('admin_enqueue_scripts',array($this, 'enqueue'));
  }
  /**
   * Defines the functionality responsible for loading the file.
   */
  public function enqueue() {
    wp_enqueue_style('tutsplus-namespace-demo',plugins_url('assets/css/admin.css', dirname(__FILE__)),array(),filemtime(plugin_dir_path(dirname(__FILE__)) . 'assets/css/admin.css'));
  }
}

C:\xampp\htdocs\test\wp-content\plugins\tutsplus-namespace-demo\admin\util\class-question-reader.php

<?php
/**
 * Reads the contents of a specified file and returns a random line from the
 * file.
 */
 
namespace Tutsplus_Namespace_Demo\Admin\Util;
class Question_Reader {
  /**
   * Retrieves a question from the specified file.
   *
   * @param  string $filename  The path to the file that contains the question.
   * @return string $question A single question from the specified file.
   */
  public function get_question_from_file($filename) {
    $question = '';
    $file_handle = $this->open($filename);
    $question    = $this->get_random_question($file_handle, $filename);
    $this->close($file_handle);
    return $question;
  }
  /**
   * Opens the file for reading and returns the resource to the file.
   *
   * @access private
   * @param  string $filename  The path to the file that contains the question.
   * @return resource          A resource to the file.
   */
  private function open($filename) {
    return fopen($filename, 'r');
  }
  /**
   * Closes the file that was read.
   *
   * @access private
   * @param  string $file_handle The resource to the file that was read.
   */
  private function close($file_handle) {
    fclose($file_handle);
  }
  /**
   * Opens the file for reading and returns the resource to the file.
   *
   * @access private
   * @param  string $file_handle The resource to the file that was read.
   * @param  string $filename    The path to the file containing the question.
   * @return string $question    The question to display in the meta box.
   */
  private function get_random_question($file_handle, $filename) {
    $questions = fread($file_handle, filesize($filename));
    $questions = explode("\n", $questions);
    // Look for a question until an empty string is no longer returned.
    $question = $questions[rand(0, 75)];
    while (empty($question)) {
      $question = $questions[rand(0, 75)];
    }
    return $question;
  }
}
?>

C:\xampp\htdocs\test\wp-content\plugins\lionel\admin\data\questions.txt

1. Do you like who you are?
2. What would people say about you at your funeral?
3. What would you regret not doing in your life?
4. What’s the wisest thing you have ever heard someone say?
5. What lessons in life did you learn to hard way?
6. How often do your biggest worries and fears come true?
7. If you had one year left to live, what would you try to achieve?
8. Do you serve money or does money serve you?
9. Are you afraid of being your true self around others? Why?
10. What are you grateful for?
11. Have you done anything you are proud of lately?
12. Have you made any recent acts of kindness?
13. If you knew that you would die tomorrow, what questions would you ask yourself?
14. If your biggest fears came true, would it matter in five years from now?
15. How would you describe yourself?
16. Do you take people’s advice?
17. Do you get quickly offended?
18. Do you consider yourself to be a likable person?
19. ‘We make a living by what we get, we make a life by what we give’ – What does this mean to you?
20. Are you enriching the lives of others?
21. Are you living a meaningful life?
22. What makes a meaningful life?
23. Would you ever give up your life to save another?
24. How much would you be willing to sacrifice for people in poverty?
25. If you could live one day over and over again, what would you choose to do?
26. Do you think you are important and worthy of affection and love?
27. What would make you feel more worthy? What do you believe needs to be different about you?
28. What brings you down the most often?
29. Would you rather work less (and do the things you enjoy) and have less money?
30. Where do you find peace?
31. What is the most important quality you look for in another person?
32. What is your biggest dream in life?
33. What is your biggest fear?
34. How would the world be different if you had never been born?
35. What life lessons do you wish you knew 10 years ago?
36. If you could tell your younger self one thing, what would it be?
37. If your life was a movie, what would the title be?
38. If your life was a movie, would you enjoy watching it?
39. What does success mean to you?
40. If you could be a different person, who would you be?
41. What was the best day of your life? Why?
42. What do you look forward to most in life?
43. What bad habits do you want to ditch?
44. Who do you look up to and why?
45. Do you know your partners love language?
46. Do the people you love most know how much you love them?
47. Are you satisfied with the depth of your relationships?
48. What do you owe yourself?
49. Based on your current day-to-day life, what do you expect to achieve in 5 years from now?
50. Do you say ‘yes’ too often when you really want to say ‘no’? Why?
51. What did you learn yesterday?
52. What do you like about yourself?
53. Would you consider yourself to be a generous person?
54. Do you really listen when people talk to you?
55. What is the number one change you need to make in your life this year?
56. How many hours per week do you spend on the internet?
57. What are your most common negative thoughts? Are they logical?
58. Do you think it’s too late to do certain things in your life? Why?
59. If you could be the most influential person in the world, what would you change?
60. How much time do you spend with your family and friends?
61. Where do you want to be in 5 years from now?
62. Is your life complicated by unnecessary things?
63. How can you simplify your life and focus on the most important things to you?
64. What stresses you out?
65. What makes life easier?
66. How often do you give without expecting anything in return?
67. What is your greatest challenge?
68. What is most important to you in life? Are you giving it the time it deserves?
69. If you could send a message to the world, what would you say in 30 seconds?
70. What do you most regret never telling someone?
71. When was the last time you tried something new?
72. Are you afraid to speak your own opinion?
73. Do you give into others too often and feel resentful because of it?
74. Are you holding onto something that you need to put behind you?
75. How often do you let your fears hold you back?
76. Do the people in your life bring the best out of you?
77. How often do you make excuses?
78. What is one mistake that you will never do again?
79. Which is worse, failing or never giving it a shot?
80. What has grown you the most as a person – your challenges and trials or the comfortable yet enjoyable moments in life?
81. If you could choose to have no more challenges or obstacles in life, would you?
82. In one word, what is standing between you and your biggest goal?
83. How often do you go to bed feeling angry?
84. Would it be wrong to steal in order to feed a starving child?
85. If you paid more attention to the sad things in this world, would you feel more conflicted about it?
86. If we learn from our failures, then why is it so bad to fail?
87. What could you pay more attention to in life?
88. Why do we think of others the most when they’re no longer around?
89. What does it look like to make the most of your life?
90. What have you given up on?
91. How many people do you truly love and what are you doing for them?
92. Do you ask enough questions, or are you happy to settle for what you already know?
93. What were you doing when you last lost track of time?
94. Do you think you would be happy if you never had to work again?
95. How old would you be if you didn’t know how old you are?
96. If you could ask for one wish, what would it be?
97. What inspires you in life?
98. What can you not live without the most?
99. What do you enjoy doing over and over again?
100. When did you last laugh so much it hurt?
101. What is stopping you from living the life you want to live?

Nếu đây là hướng dẫn đầu tiên mà bạn đang đọc trong loạt bài này, thì tôi khuyên bạn nên theo kịp những gì mà chúng tôi đã khái quát cho đến lúc này.

Về cơ bản, bạn đang đến với phần cuối của loạt bài. Tại thời điểm này, chúng ta đã đặt nền móng cho plugin của chúng ta, viết plugin và định nghĩa và tìm hiểu không gian tên và autoload. Tất cả những gì còn lại là áp dụng những gì mà chúng ta đã học.

Vì vậy trong hướng dẫn này, chúng ta sẽ kết hợp tất cả lại với nhau. Cụ thể, chúng ta sẽ xem lại mã nguồn của plugin, tổ chức tất cả các lớp có liên quan theo không gian tên, và viết một autoload để chúng ta có thể xóa tất cả các câu lệnh include của chúng ta.

Tôi sẽ thảo luận chi tiết tất cả mọi thứ khi chúng ta làm việc trên code. Một lần nữa, nếu đây là hướng dẫn đầu tiên bạn đang đọc trong loạt bài này, hãy theo kịp với những gì mà chúng tôi đã đề cập đến và sau đó quay trở lại hướng dẫn này.

Trước khi Chúng ta Viết Bất kỳ Code nào

Tại thời điểm này, bạn chắc là đã nắm vững cách chúng ta thiết lập môi trường phát triển của chúng ta. Nhắc lại một chút, đây là phần tóm lược nhanh về những phần mềm mà chúng ta đang sử dụng:

  • ít nhất là PHP 5.6.20

  • máy chủ web Apache

  • một máy chủ cơ sở dữ liệu MySQL

  • WordPress 4.6.1

  • kiến thức về WordPress Plugin API

Bạn cũng sẽ cần mã nguồn của plugin mà chúng ta đang làm việc. Bạn có thể tải về một phiên bản của nó ngay tại đây. Giả sử nó đã được cài đặt, kích hoạt, và bạn đã có một IDE, chúng ta hãy bắt đầu.

Áp dụng Không gian tên

Nhắc lại hướng dẫn trước, tôi là một fan hâm mộ trong việc đảm bảo rằng không gian tên của chúng ta tuân theo cách tổ chức của các tập tin trên ổ đĩa. Nếu bạn nhìn vào cấu trúc thư mục của plugin hoặc nếu bạn đã theo dõi loạt bài cho đến lúc này, thì bạn sẽ thấy một vài thứ như sau:

Lưu ý rằng, nếu bạn đã cài đặt plugin của bạn theo cách khác, thì cũng tốt thôi. Không gian tên của bạn có thể sẽ khác, nhưng điều đó không ảnh hưởng đến bất cứ điều gì được đề cập trong loạt bài này cả.

Sử dụng cấu trúc thư mục làm tham chiếu, chúng ta hãy đi qua tất cả các tập tin PHP tạo nên plugin của chúng ta và định nghĩa không gian tên của chúng. Thực hiện điều này rất dễ: Chỉ cần sử dụng từ khoá namespace và đặt tên đủ tiêu chuẩn ở đầu mỗi tập tin.

Tôi sẽ liệt kê từng cái ở dưới đây.

tutsplus-namespace-demo.php

010203040506070809101112131415161718192021222324252627282930

<?php/** * The plugin bootstrap file * * This file is read by WordPress to generate the plugin information in the * plugin admin area. This file also includes all of the dependencies used by * the plugin, registers the activation and deactivation functions, and defines * a function that starts the plugin. * * @link https://.tutsplus.com/tutorials/using-namespaces-and-autoloading-in-wordpress-plugins-part-1 * @since 0.1.0 * @package tutsplus_namespace_demo * * @wordpress-plugin * Plugin Name: Tuts+ Namespace Demo * Plugin URI: http://.tutsplus.com/tutorials/using-namespaces-and-autoloading-in-wordpress-plugins-part-1 * Description: Learn how to use Namespaces and Autoloading in WordPress. * Version: 0.2.0 * Author: Tom McFarlin * Author URI: https://tommcfarlin.com/ * License: GPL-2.0+ * License URI: http://www.gnu.org/licenses/gpl-2.0.txt */ namespace Tutsplus_Namespace_Demo; // If this file is accessed directory, then abort.if ( ! defined( 'WPINC' ) ) { die;}

class-meta-box.php

123456

<?php/** * Represents a meta box to be displayed within the 'Add New Post' page. */ namespace Tutsplus_Namespace_Demo\Admin;

Advertisement

class-meta-box-display.php

1234567

<?php/** * Defines the functionality required to render the content within the Meta Box * to which this display belongs. */ namespace Tutsplus_Namespace_Demo\Admin;

interface-assets.php

12

<?phpnamespace Tutsplus_Namespace_Demo\Admin\Util;

class-css-loader.php

123456

<?php/** * Provides a consistent way to enqueue all administrative-related stylesheets. */ namespace Tutsplus_Namespace_Demo\Admin\Util;

Advertisement

class-question-reader.php

1234567

<?php/** * Reads the contents of a specified file and returns a random line from the * file. */ namespace Tutsplus_Namespace_Demo\Admin\Util;

Có một số thứ cần lưu ý về các quy ước mà tôi đã sử dụng ở trên:

  • Không gian tên gốc là Tutsplus_Namespace_Demo, tương ứng với tên thư mục của plugin.

  • Phần còn lại của không gian tên chẳng hạn như Tutsplus_Namespace_Demo\AdminTutsplus_Namespace_Demo\Admin\Util cũng tương đương với các thư mục tương ứng của chúng; Tuy nhiên, các tên thư mục được đặt ở dạng viết hoa chữ cái đầu (so với chữ thường).

Và nó bao gồm thông báo sau:

PHP Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'tutsplus_namespace_demo' not found or invalid function name in /Users/tommcfarlin/Dropbox/Projects/tutsplus/wp-includes/plugin.php on line 524

Hoặc có thể nó hiển thị:

PHP Fatal error: Class 'Meta_Box' not found in /Users/tommcfarlin/Dropbox/Projects/tutsplus/wp-content/plugins/tutsplus-namespace-demo/tutsplus-namespace-demo.php on line 48

Hoặc bạn có thể trông thấy bất kỳ số lượng các thông báo lỗi tương tự khác. Điều đó không sao cả. Nó bình thường thôi.

Nhưng câu hỏi đặt ra là: Điều gì xảy ra với plugin của chúng ta? May mắn thay, không có gì cả. Đây là hành vi như mong đợi.

Thông báo đầu tiên mà bạn nhìn thấy có thể là kết quả của một plugin khác mà bạn đã cài đặt. Tôi không thể mô phỏng lại nó; Tuy nhiên, khi tôi hủy kích hoạt một vài plugin khác mà tôi đang chạy, thì plugin tạo ra thông báo thứ hai (đó là thông báo mà tôi muốn minh hoạ).

Khi bạn áp dụng không gian tên, PHP kỳ vọng xác định vị trí một lớp bên trong một không gian tên nhất định. Về mặt khái niệm, bạn có thể hình dung các lớp của bạn bây giờ thuộc về gói của riêng nó (hoặc gói con) hoặc tuỳ theo cách bạn xác định nó. Và để cho một hàm truy cập vào một lớp trong một gói, nó cần phải nhận biết các các gói tồn tại.

Đây là nơi tính năng bổ sung của không gian tên và autoload phát huy tác dụng. Vì vậy, trước khi chúng ta cố gắng truy cập vào code của chúng ta thông qua không gian tên của chúng, thì chúng ta hãy làm việc trên một autoload.

Tất cả Xoay quanh Autoload

Viết một autoload sẽ đòi hỏi những thứ sau đây:

  1. hiểu rõ một hàm PHP có tên là spl_autoload_register

  2. viết một hàm mà sẽ tự động nạp các tập tin đã áp dụng không gian tên của chúng ta

  3. include hàm autoload tuỳ biến của chúng ta

Đừng để cái tên spl_autoload_register đe doạ bạn. Nó chỉ đơn giản có nghĩa đây là một hàm nằm trong "Thư viện PHP Tiêu chuẩn" và đó là cách chúng ta "đăng ký" hàm "autoload". Đó là một câu nói cửa miệng và rất nhiều ký tự để viết, nhưng nó chỉ là một hàm mà chúng ta sẽ sử dụng để nói với PHP cách để phân tích không gian tên và tên lớp và nơi nó có thể tìm thấy các tập tin của chúng ta.

Hàm này là những gì cho phép chúng ta viết code riêng của chúng ta cho các tập tin autoload và sau đó hook hàm đã nói vào PHP. Nghĩa là, chúng ta sẽ nói cho PHP nơi để tìm các tập tin của chúng ta và cách phân tích không gian tên, tên tập tin, vân vân, để nó include các tập tin.

Với tất cả những điều đã nói, chúng ta đã sẵn sàng để thật sự viết một autoload.

Viết một Autoload

Khi viết một autoload, điều cần ghi nhớ là cách các tập tin của chúng ta được tổ chức. Nghĩa là, chúng ta muốn biết cách để ánh xạ không gian tên vào thư mục của chúng ta.

Trong ví dụ mà chúng ta đang sử dụng, nó đơn giản: Các không gian tên là các phiên bản được viết hoa ký tự đầu của cấu trúc thư mục. Điều này không phải lúc nào cũng đúng cho các dự án khác; tuy nhiên, đó là một lý do khác lý giải tại sao tôi muốn tổ chức hợp lý các tập tin của tôi dựa trên vị trí thật của chúng.

Khi PHP cố gắng nạp một lớp, autoload của chúng ta sẽ cần phải làm như sau:

  1. Phân tách không gian tên dựa trên dấu gạch chéo.

  2. Phân tách gói và các gói con dựa trên dấu gạch dưới và thay thế bằng dấu gạch nối (nếu cần).

  3. Biết cách ánh xạ tên lớp, giao diện, và vân vân thành tên tập tin.

  4. Tạo một chuỗi đại diện cho tên tập tin dựa trên các thông tin ở trên.

  5. Bao gồm một tập tin.

Với tất cả những điều đó đã được thực hiện xong, chúng ta đã có được mọi thứ thích hợp cho chúng ta. Trong thư mục plugin, hãy tạo một thư mục con đặt tên là inc, và trong thư mục inc tạo một tập tin có tên là autoload.php.

Trong tập tin đó, hãy tiếp tục và trích ra hàm mà chúng ta sẽ sử dụng để autoload các tập tin của chúng ta. Nó sẽ trông giống như sau:

01020304050607080910111213141516171819202122232425262728293031

<?php/** * Dynamically loads the class attempting to be instantiated elsewhere in the * plugin. * * @package Tutsplus_Namespace_Demo\Inc */ spl_autoload_register( 'tutsplus_namespace_demo_autoload' ); /** * Dynamically loads the class attempting to be instantiated elsewhere in the * plugin by looking at the $class_name parameter being passed as an argument. * * The argument should be in the form: TutsPlus_Namespace_Demo\Namespace. The * function will then break the fully-qualified class name into its pieces and * will then build a file to the path based on the namespace. * * The namespaces in this plugin map to the paths in the directory structure. * * @param string $class_name The fully-qualified name of the class to load. */function tutsplus_namespace_demo_autoload( $class_name ) { // If the specified $class_name does not include our namespace, duck out. if ( false === strpos( $class_name, 'Tutsplus_Namespace_Demo' ) ) { return; } // More to come...}

Rõ ràng, điều này vẫn chưa thực hiện bất cứ điều gì cả.

Một Lưu ý Ngoài lề Trong việc Viết một Autoload

Lưu ý rằng tôi sẽ viết code và chú thích để giải thích một cách đầy đủ những gì chúng ta đang làm. Nếu bạn tự liều mình làm điều này lần đầu tiên, thì việc viết một autoload cùng với việc sử dụng không gian tên và làm việc với các tập tin có thể làm bạn thấy nản. Đây là nơi một trình sửa lỗi và sử dụng các tập tin log (nhật ký) trở nên có ích.

Điều này vượt ra ngoài phạm vi của hướng dẫn này, nhưng hãy biết rằng, viết một autoload không phải là điều mà bạn có thể làm đúng ngay lần đầu tiên bạn thực hiện nó.

Hoàn tất Autoload

Hãy bắt đầu thêm một số chức năng cho các bước được liệt kê lúc bắt đầu phần này.

Trước tiên, chúng ta cần phải thiết lập một vòng lặp mà sẽ lặp ngược qua các phần của tên tập tin được truyền vào hàm autoload. Chúng ta làm điều này là bởi vì nó giúp dễ dàng hơn để xây dựng một đường dẫn đến tập tin để autoload.

0102030405060708091011121314151617

<?phpfunction tutsplus_namespace_demo_autoload( $class_name ) { // If the specified $class_name does not include our namespace, duck out. if ( false === strpos( $class_name, 'Tutsplus_Namespace_Demo' ) ) { return; } // Split the class name into an array to read the namespace and class. $file_parts = explode( '\\', $class_name ); // Do a reverse loop through $file_parts to build the path to the file. $namespace = ''; for ( $i = count( $file_parts ) - 1; $i > 0; $i-- ) { // More to come... }}

Sau điều này, chúng ta cần phải tìm kiếm tập tin $file_parts và thay thế tất cả các lần xuất hiện của dấu gạch dưới bằng một dấu gạch nối bởi vì tất cả các tên lớp và giao diện của chúng ta sử dụng dấu gạch dưới trong khi tên tập tin của chúng ta sử dụng dấu gạch nối.

Hai dòng sau đây là hai dòng đầu tiên bên trong vòng lặp mà chúng ta đã trích ra ở trên:

12345

<?php // Read the current component of the file part.$current = strtolower( $file_parts[ $i ] );$current = str_ireplace( '_', '-', $current );

Tiếp theo, chúng ta sẽ cần một điều kiện để thực hiện một vài thứ.

  1. Nó cần phải kiểm tra để xem phân đoạn nào của đường dẫn của tên tập tin mà chúng ta đang đọc.

  2. Nếu chúng ta đang ở phân đoạn đầu tiên, thì chúng ta đang ở tại tên tập tin; Nếu không, chúng ta đang ở trong không gian tên của nó.

  3. Tiếp theo, nếu chúng ta đang đọc phân đoạn đầu tiên, chúng ta cần phải xác định xem chúng ta đang cố autoload một giao diện hay chúng ta đang nạp một lớp.

  4. Nếu đó là giao diện, thì chúng ta cần phải điều chỉnh tên của giao diện để chúng ta nạp nó một cách hợp lý dựa trên tên tập tin của nó; nếu không, chúng ta sẽ nạp lớp dựa trên giá trị trong biến $current.

Đọc ra thì rất nhiều, nhưng nó không đến nỗi quá phức tạp. Hãy xem các chú thích code dưới đây:

010203040506070809101112131415161718192021222324

<?php // If we're at the first entry, then we're at the filename.if ( count( $file_parts ) - 1 === $i ) { /* If 'interface' is contained in the parts of the file name, then * define the $file_name differently so that it's properly loaded. * Otherwise, just set the $file_name equal to that of the class * filename structure. */ if ( strpos( strtolower( $file_parts[ count( $file_parts ) - 1 ] ), 'interface' ) ) { // Grab the name of the interface from its qualified name. $interface_name = explode( '_', $file_parts[ count( $file_parts ) - 1 ] ); $interface_name = $interface_name[0]; $file_name = "interface-$interface_name.php"; } else { $file_name = "class-$current.php"; }} else { $namespace = '/' . $current . $namespace;}

Xong những cái đó, đến lúc tạo một đường dẫn đủ điều kiện đến tập tin. May mắn thay, điều này cơ bản hơn việc nối chuỗi một chút:

12345

<?php // Now build a path to the file using mapping to the file location.$filepath = trailingslashit( dirname( dirname( __FILE__ ) ) . $namespace );$filepath .= $file_name;

Cuối cùng, chúng ta cần phải chắc chắn rằng tập tin có tồn tại. Nếu không, chúng ta sẽ hiển thị một thông báo lỗi tiêu chuẩn của WordPress:

01020304050607080910

<?php // If the file exists in the specified path, then include it.if ( file_exists( $filepath ) ) { include_once( $filepath );} else { wp_die( esc_html( "The file attempting to be loaded at $filepath does not exist." ) );}

Và tại thời điểm này, chúng ta có một autoload đầy đủ (có thể được tải về bằng liên kết trong thanh sidebar của bài viết này vì mã nguồn quá dài để có thể đăng ở trong hướng dẫn).

Cuối cùng, điều quan trọng cần lưu ý là hàm đặc biệt này có thể (hoặc nên) được viết lại như là một lớp. Hơn nữa, lớp này nên bao gồm một số hàm nhỏ hơn để dễ kiểm thử, chịu trách nhiệm thực hiện một nhiệm vụ duy nhất, và rõ ràng hơn những gì ở trên. Có lẽ trong một hướng dẫn khác, tôi sẽ khái quát quá trình đó sẽ như thế nào.

Nhưng Chúng ta Vẫn đang Include các Tập tin

Nếu bạn nhìn vào gần phía trên của tập tin chính của plugin (hoặc tập tin mà chúng ta thường gọi là tập tin khởi động), bạn sẽ thấy một số câu lệnh include như sau:

01020304050607080910

<?php // Include the files for rendering the display.include_once( 'admin/class-meta-box.php' );include_once( 'admin/class-meta-box-display.php' );include_once( 'admin/util/class-question-reader.php' ); // Include the files for loading the assetsinclude_once( 'admin/util/interface-assets.php' );include_once( 'admin/util/class-css-loader.php' );

Với công việc mà chúng ta đã thực hiện cho đến lúc này, cuối cùng chúng ta cũng có thể loại bỏ các câu lệnh này và thay thế chúng bằng một cái duy nhất:

1234

<?php // Include the autoloader so we can dynamically include the rest of the classes.require_once( trailingslashit( dirname( __FILE__ ) ) . 'inc/autoloader.php' );

Hay nói đúng hơn, chúng ta đang thay thế nó bằng autoload của chúng ta. Tại thời điểm này, chúng ta chắc đã hoàn tất plugin của chúng ta.

Tổng hợp

Bây giờ thì chúng ta đã áp dụng không gian tên cho code của chúng ta để cung cấp một cách tổ chức hợp lý các lớp có liên quan, và viết một autoload để tự động include các tập tin dựa trên không gian tên và vị trí của từng lớp, chúng ta có thể khởi động plugin của chúng ta và nó hoạt động hoàn toàn giống với phiên bản đầu tiên.

Điều cuối cùng mà chúng ta cần làm là đảm bảo rằng chúng ta cập nhật tập tin khởi động để chúng ta hướng dẫn PHP sử dụng không gian tên cho Meta_Box, Meta_Box_Display, Question_ReaderCSS_Loader.

01020304050607080910111213141516171819202122232425262728293031

<?php use Tutsplus_Namespace_Demo\Admin;use Tutsplus_Namespace_Demo\Admin\Util; // If this file is accessed directory, then abort.if ( ! defined( 'WPINC' ) ) { die;} // Include the autoloader so we can dynamically include the rest of the classes.require_once( trailingslashit( dirname( __FILE__ ) ) . 'inc/autoloader.php' ); add_action( 'plugins_loaded', 'tutsplus_namespace_demo' );/** * Starts the plugin by initializing the meta box, its display, and then * sets the plugin in motion. */function tutsplus_namespace_demo() { $meta_box = new Admin\Meta_Box( new Admin\Meta_Box_Display( new Util\Question_Reader() ) ); $css_loader = new Util\CSS_Loader(); $css_loader->init(); $meta_box->init();}

Lưu ý trong đoạn code ở trên, chúng ta đang sử dụng từ khóa use của PHP, và chúng ta đang thêm tiền tố vào tên lớp của chúng ta bằng các gói con trực tiếp. Bạn có thể đọc thêm về use trong hướng dẫn sử dụng, nhưng một cách ngắn gọn nó là:

Từ khóa use phải được khai báo ở phạm vi ngoài cùng của một tập tin (phạm vi toàn cục) hoặc bên trong các khai báo không gian tên. Điều này là do việc import được thực hiện lúc biên dịch mà không phải là lúc chạy, vì vậy nó không thể bị khoá phạm vi.

Nếu vậy, thì xin chúc mừng. Bạn đã xây dựng thành công plugin của bạn để áp dụng không gian tên và autoload. Nếu không, hãy kiểm tra lại code của bạn với code mà chúng tôi đã chia sẻ ở đây, xem lại nhật ký (log) lỗi của bạn và đảm bảo rằng không có gì khác thường hiển thị trên màn hình chính của WordPress.

Nếu bạn thật sự thấy một cái gì đó, cá là nó có liên quan đến một thứ gì đó không đáng kể. Hãy xem lại code mà chúng ta đã thảo luận, so sánh code này với nội dung tập tin đính kèm trong bài viết này (trong thanh side cùng với nút màu xanh lớn) và xem bạn có thể thu hẹp được vấn đề hay không.

Tóm tắt

Tại thời điểm này, chúng ta đã đi đến phần kết thúc của loạt bài này. Xuyên suốt bốn hướng dẫn, chúng ta đã đề cập đến rất nhiều vấn đề:

  • Chúng ta đã xây dựng một plugin nhắc người dùng bằng các câu hỏi để giúp họ bắt đầu viết blog.

  • Chúng ta đã sử dụng các hàm PHP để đọc các tập tin từ hệ thống và kết xuất nó lên trên màn hình.

  • Chúng ta đã định nghĩa không gian tên và autoload, và tìm hiểu cách chúng có thể được áp dụng.

  • Chúng ta đã tổ chức code và viết autoload của chúng ta, làm cho code dễ đọc, được tổ chức tốt và ít lộn xộn hơn.

Cuối cùng, rất nhiều kiến thức được đề cập trong loạt bài này có thể được sử dụng trong các dự án hiện tại và tương lai mà bạn có thể làm việc.

Hãy nhớ rằng, bạn cũng có thể tìm thấy các sản phẩm khác liên quan đến WordPress trên Market của chúng tôi. Và nếu bạn muốn tìm hiểu thêm về việc phát triển các giải pháp cho WordPress, thì bạn có thể tìm thấy tất cả các hướng dẫn và loạt bài viết trên trang tiểu sử của tôi. Đừng ngần ngại theo dõi tôi trên blog hoặc trên Twitter của tôi vì tôi thảo luận về phát triển phần mềm trong ngữ cảnh của WordPress hầu như hàng ngày.

Và hãy nhớ rằng, liên kết để tải mã nguồn hoàn chỉnh là trong thanh sidebar, trong nút có tiêu đề Download Attachment. Tất nhiên, đừng ngần ngại đặt bất kỳ câu hỏi nào và đưa ra ý kiến của bạn!

Last updated