Home > Article > Backend Development > Discover Functional Programming: A Path to Developing WordPress Plugins
The second part of this series looks at two different programming styles (sometimes called programming paradigms) that you can use when writing WordPress plugins. In Part One, Tom McFarlin introduces object-oriented programming. In this part, we will discuss functional programming.
Since the experience levels of readers vary, we will be discussing advanced programming, so if you are a beginner you should have no problem. However, if you are an experienced developer, you may find more useful information later in this article.
Functional programming is probably the style you are most familiar with and is almost universally used and is the style used by various WordPress snippet sites on the internet. Therefore, it can sometimes be considered "entry-level" programming: the style that beginners adopt before they learn to master object-oriented programming. This is incredibly misleading, because while functional programming is much simpler, it's not inherently inferior.
Functional programming emphasizes the evaluation of functions and avoids the concept of state or objects, as opposed to object-oriented programming, which encourages thinking of code as acting on objects, using methods to change those objects or interact with them . Let's look at a very simple example to compare these two styles:
// Functional method function add_two( $n ) { return $n +2; } $a = 2; $b = add_two( $a ); // $b = 4; // Object oriented method class Number { var $value = 0; function __construct( $a ) { $this->value = $a; } function add_two() { $this->value = $this->value +2; } } $a = new Number( 2 ); echo $a->value; //Prints 2 $a->add_two(); echo $a->value; //Prints 4
This very simple example illustrates the fundamental difference in style between the two paradigms: Functional programming focuses on passing parameters to functions and receiving values from functions. There is no "object" being acted upon, only parameters and return values. In contrast, the object-oriented approach assigns various properties ("values" in our case) to objects, and methods act on these properties.
Defining a function is very simple:
function add( $number, $number2 = 1 ) { // Perform code acting on passed variables $sum = $number + $number2; // Optional, if needed you can return a value return $sum; }
After you declare a function, it can be used anywhere in the plugin - in other words, it has global scope.
$a = 4; $b = 7; echo add( $a, $b ); // Prints 11Functions must have unique names. Redeclaring a function throws an error. Since your code will run with other plugins, themes, and WordPress itself, you should never use generic names. Instead, you should add some unique prefix to the function name (such as the name of the plugin).
You may have noticed that in the definition of add
, the second parameter is set equal to 1
. This sets a default value for $number2
(in this case 1), thus making the parameter optional. If no argument is provided, the value will be treated as the default:
echo add( 4 ); // Prints 5 echo add( 4, 1 ); // Prints 5
On the other hand, no default value is provided for the first value, so omitting this parameter will raise an error
echo add(); // Throws an error as $number is not defined
You can also have a variable number of parameters. Inside a function we can use func_num_args()
to get the number of arguments received, while func_get_arg()
allows you to access specific passed variables, indexed starting from 0.
function sum() { // Get the number of arguments given to sum() $number_args = func_num_args(); $sum = 0; if ( ! $number_args ) return $sum; for ( $i = 0; $i < $number_args; $i++ ) { $sum += func_get_arg( $i ); } return $sum; } echo sum( 1, 2, 3, 4 ); //Prints 10 echo sum( 1, 2 ); //Prints 3 echo sum(); //Prints 0
The above content can also be used in object methods. Finally, by declaring a variable as "global" you can access it from inside the function.
$a = 'Hello'; $b = 'World'; function hello_world() { // This is necessary to access $a and $b // declared outside of the function scope. global $a, $b; $b = $a . ' ' . $b; } hello_world(); echo $b; // Prints 'Hello World'The use of global variables is generally discouraged. Especially since two plugins using the same name for a global variable can cause one or both plugins to break. If you must use a global variable, again make sure it is unique by prefixing it with the plugin name.
Deciding which programming style to use comes down to judgment and - yes - personal preference. It's not more correct or wrong to use functional programming instead of object-oriented programming, but usually there is a style that is better suited for what you want to achieve.
Sometimes object-oriented programming is simply not necessary and only makes things overly complicated or introduces redundant code. An example might be the various “utility” features provided by WordPress. These are general functions used to perform a specific purpose. For example wp_trim_words( $text, $num_words )
just trims the given string to a certain size (in words). It adds nothing to define wp_trim_words()
as a method belonging to some object, and results in uglier code. For functional programming, just one line.
One of the advantages of functional programming is its simplicity, especially for beginners. You don't have to worry about static, private or protected functions - they are all global. The concept of static variables also does not exist. At the most basic level, your function returns an output derived from what you give it. For example, get_the_title( 7 )
will return the title of the post with ID 7.
Another advantage of functional programming is that functions can be accessed globally. For object-oriented programs, in order to operate on a specific object, you need to pass that object. This can sometimes be tricky. To illustrate this, let's take the example from part one:
class DemoPlugin { public function __construct() { add_action( 'wp_enqueue_scripts', array( $this, 'register_plugin_scripts' ) ); } public function register_plugin_scripts() { // Register plugin scripts } } $demo_plugin = new DemoPlugin();
当 WordPress 存储 register_plugin_scripts()
方法时,以便在触发 wp_enqueue_scripts
操作时调用它,它不仅通过引用该方法,而且还引用对象 $demo_plugin
来实现此目的。这是因为同一对象的不同实例的相同方法被视为不同的方法 - 即 $demo_plugin->register_plugin_scripts()
和 $copy_of_demo_plugin->register_plugin_scripts()
不是相同。这可能看起来很奇怪 - 但对于同一类的不同实例,方法的行为可能不同,因此我们需要引用方法和实例。
但是为什么这很重要呢?这使得第三方插件或主题很难取消该方法,因为为此他们需要调用:
remove_action( 'wp_enqueue_scripts', array( $demo_plugin, 'register_plugin_scripts' ) );
但通常他们无法访问 $demo_plugin
变量。 (注意:如果该方法被声明为静态,那么您可以解决这个问题)。
当然,面向对象编程有其优点,如第一部分所述。正如 Tom 还提到的,使用 WordPress 的小部件 API 时这是不可避免的。另一个常见的例子是 WP_Query()
。在这里,面向对象的方法显然是最好的:您有一个对象(在本例中是一个查询),它具有各种属性(即搜索条件、分页信息、匹配结果),并且您想要对该查询进行操作(解析它,生成并清理相应的SQL,并返回结果)。
WP_Query()
演示了正确使用时面向对象编程的强大功能。发起查询后:
$the_query = new WP_Query( array(...) );
您不仅可以访问结果,还可以访问其他信息,例如分页值:有多少页结果、正在查看哪个页面、结果总数以及查询的“类型”,例如$the_query->is_search()
、$the_query->is_single()
等。还有整个“循环”基础设施;
if ( $the_query->have_posts() ) { echo '<ul>'; while( $the_query->have_posts() ): $the_query->the_post(); // The Loop echo '<li>' . get_the_title( $the_post->ID ) . '</li>'; endwhile; echo '</ul>'; } wp_reset_postdata();
它将结果和全局变量的所有内部处理隐藏在人性化的 API 后面。
那么 get_posts()
呢?这只是作为 WP_Query()
的包装器,并简单地返回与查询匹配的帖子数组。因此,您不会得到 WP_Query()
的“花哨”功能,但它的效率稍高一些。因此,是否应该使用 get_posts()
还是 WP_Query()
取决于您的用例(例如,是否需要分页),但这也取决于个人喜好。
$results = get_posts( array( ... ) ); if ( $results ) { echo '<ul>'; foreach( $results as $the_post ) { echo '<li>' . get_the_title( $the_post->ID ) . '</li>'; } echo '</ul>'; }
希望这两篇文章有助于突出这些编程风格的优点和缺点。要点是,这里没有对与错,每个程序员都有自己的个人偏好。但某些上下文更容易适应某种编程风格 - 因此您应该期望您的插件包含两者的混合。
The above is the detailed content of Discover Functional Programming: A Path to Developing WordPress Plugins. For more information, please follow other related articles on the PHP Chinese website!