Use of declaring empty function in php - php

while seeing word press core code in depth i came across a file which has many empty functions for eg :
/**
* #ignore
*/
function apply_filters() {}
i realy dont know what is the use of declaring empty function in php..
i found this in wp-admin/list-scripts.php on line 34 - 37
and in wp-include/plugin.php on line 163 - 207 the same function is re declared with some works in it
In total i have 2 questions
What is the use of declaring an empty function in php
Why wordpress din't show any Fatal error: as the same function is already declared. ?

In PHP (and many other OOP languages), an empty function (or, more precisely, method) can be used in an interface. Any class inheriting that interface must implement the declared functions. However, last time I checked (which is, 2 minutes ago), WordPress isn't really an OOP system, so forward to 2.
list-scripts.php is not a default WordPress file - I can't find it in any of my WP installation. You may want to test by putting a die('called'); on top of the file and see if it gets executed. Therefore, WordPress won't encounter duplicated function declaration, and no fatal errors are introduced.
Now, even if list-scripts.php is a default WP file, when working with WP (and PHP in general) more often than not you see this:
if (!function_exists('apply_filters')) {
function apply_filters($arg1, $arg2) {
// code is poetry
}
}
This makes sure a function is only declared if it hasn't been before, and avoids the fatal error.

I guess wordpress will conditionally include either one or the other file. A lower level API of wordpress expects this functions to be defined and calls them. The extension itself is free to implement the function or not, however it has at least to provide the empty function body. The concepts behind this are much like interfaces work in OOP.

Related

Wordpress: False function re-declare error?

I know php, but very new to wordpress. and I just don't want to learn this stuff, only need to change something for a short while,
I am declaring a function in file
var/www/wp-content/plugins/woocommerce/templates/checkout/thankyou.php
function cr (){
}
But wordpress gives me error
Can't redeclare function cr() (previously declared on line no..xxx) in file ....
now the line number it mentions is the only place where this function is declared, This is what I tried :
tried to rename the function to very uncommon names and every time the same error.
wrapped the function in
if(!function_exists('cr')) {
function cr() {
..
..
}
}
I get an error :
Fatal error: Call to undefined function cr() in
/var/www/storearn/wp-content/plugins/woocommerce/templates/checkout/thankyou.php
on line 74
What could be the reason?
You're declaring the function in the wrong file.
Firstly, template files are the wrong place to declare a function. It belongs either within a custom plugin or your theme (functions.php or some file included from there). Ideally a custom plugin but it would depend on context. With the plugin placed in the right location there shouldn't be any risk of it being duplicated. You may also want to prefix it too.
The second issue I see is that you're attempting to modify files within the WooCommerce plugin itself. As soon as you update WC, those modifications will be overwritten. Templates should be overridden individually within your theme.
Documentation: https://docs.woocommerce.com/document/template-structure/

How can I check a php file for undefined functions?

Calling php -l checks the syntax of a php file.
Is there a way to check for undefined functions? I don't need it to work with functions defined at runtime nor with dynamic calls.
Calling the file obviously won't work: I need to check the whole file, not only the branch that gets executed. See the follwing example.
myfile.php:
function imhere () {}
main.php:
require_once 'myfile.php';
if (true) {
imhere();
}
else {
imnhothere(); // I need to get a warning about this
}
Checking for undefined functions is impossible in a dynamic language. Consider that undefined functions can manifest in lots of ways:
undefined();
array_filter('undefined', $array);
$prefix = 'un'; $f = $prefix.'defined'; $f();
This is in addition to the fact that there may be functions that are used and defined conditionally (through includes or otherwise). In the worst case, consider this scenario:
if(time() & 1) {
function foo() {}
}
foo();
Does the above program call an undefined function?
Check the syntax only need to scan the current content of the php file, but check for function defined or not is something different because functions could be defined in the required file.
The simplest way is just to execute the file, and undefined function will give you a PHP Fatal error: Call to undefined function .....
Or you may want this.
Following comment tennis I thought I would wrap up some thoughts into an answer.
It seems like what you might need is some higher-level testing (either integration or web testing). With these you can test complete modules or your whole application and how they hang together. This would help you isolate calls to undefined functions as well as a host of other things by running tests against whole pages or groups of classes with the relevant includes statements. You can PHPunit for integration testing (as well as for unit-) although I'm not sure that would gain you that much at this point.
Better would be to investigate web-testing. There are a number of tools you could use (this is by no means intended to be a complete list):
Selenium which I believe can hook into PHPUnit
SimpleTest, not sure how well maintained this is but I have used it in the past for simple (!) tests
behat, this implements BDD using Gherkin but I understand it can be used to do web-testing (behat with Goutte

Does function definition order matter?

In the script below, does the order in which items are declared matter?
For example, if the add_action points to a function that has not yet been defined? Does it matter or should the function declaration always precede any code in which its called?
add_action('load-categories.php', 'my_admin_init');
function my_admin_init(){
//do something
}
That doesn't matter if the function is declared before or after the call but the function should be there in the script and should be loaded in.
This is the first method and it will work:
some_func($a,$b);
function some_func($a,$b)
{
echo 'Called';
}
This is the second method and will also work:
function some_func($a,$b)
{
echo 'Called';
}
some_func($a,$b);
From the PHP manual:
Functions need not be defined before they are referenced, except when a function is conditionally defined as shown in the two examples below.
However, while this is more of a personal preference, I would highly recommend including all the functions you actually use in an external functions.php file then using a require_once() or include_once() (depending on tastes) at the very top of your main PHP file. This makes more logical sense -- if someone else is reading your code, it is blindingly obvious that you are using custom functions and they are located in functions.php. Saves a lot of guesswork IMO.
you can call a function before it's defined, the file is first parsed and then executed.
No.
It is not C :P...
As you can see here , the whole file is first being parsed and then executed.
If a function that doesn't exist is being called, php will throw an error.
Fatal error: Call to undefined function
As per my personal experience, In some special cases (Like, passing array's in function or function inside a function and so on). It's best option to define the function above the call. Because of this sometimes neither function works nor PHP throw an error.
In normal php functions, it doesn't matter. You can use both of the types.
It does not matter, as long as it is declared somewhere on the page.
as seen here:
http://codepad.org/aYbO7TYh
Quoting the User-defined functions section of the manual :
Functions need not be defined before
they are referenced, except when a
function is conditionally defined
So, basically : you can call a function before its definition is written -- but, of course, PHP must be able to see that definition, when try to call it.

Is it important to explicitly declare properties in PHP?

I have followed a tutorial to create a simple blog writing application in PHP and have modified the classes in this tutorial so that they have additional capabilities. Modifying this very bare bones app has given me a better understanding of how PHP works, however I have run across an interesting situation.
One of the classes in my project has about a half dozen class properties such as public $id, public $author, public $post. These properties are declared at the beginning of this class however I find that if I remove all but one of these properties the app still functions correctly.
Is it wrong to remove a property declaration such as public $datePosted from the beginning of a class if this class still assigns variables to this property like this: $this->datePosted = $someVariableName;
If you try to access a class property which hasn't been declared, PHP will issue a notice:
class Foo { }
var $fu = new Foo();
echo $fu->baz;
Notice: Undefined property: Foo::$baz in blah.php on line 4
If you set a value first ($fu->baz = 'blah') then it won't complain, but that's not a great situation.
You should definitely declare all your class variables (unless of course you want to have some fun with the magic methods)...
it's clearer for anyone reading your code that the members have been explicitly defined as public rather than just defaulting to it because you haven't assigned them as being public members.
Also, $this->$datePosted is wrong, it should be like this:
$this->datePosted = $someVariable;
which may be why you are experiencing an error.
PHP is really loose about how it handles class member definitions. You technically don't have to declare them. But you should, for two big reasons:
People with smart IDE's (Eclipse, Aptana, Zend Studio) will love if they can take advantage of their editor's code intellisense (auto-complete) while working with your classes. This feature really helps prevent against bugs involving typos. If you don't declare your fields, the IDE has no real way of determining the class' fields.
Someone just getting done working with a compiled language (C++) will likely send a hitman after you if they see a lack of properly-defined fields. It's just good practice to declare them. There's no reason not to.
Also, if you remove declaration and the code reads this variable prior to writting to it, you will have an error like
PHP Notice: Undefined property:
A::$unexistent in C:\temp\test.php on
line 8
Notice: Undefined property:
A::$unexistent in C:\temp\test.php on
line 8

Wordpress register_activation_hook() + global variables + class: cannot redeclare

I'm writing my first wordpress plugin and I'm trying to create a function to be called when the plugin is activated.
Currently it looks like this:
class ThumbsUp {
...
}
global $thumbs;
function thumbs_install() {
//global $thumbs;
$thumbs = new ThumbsUp(); /* Line 160 */
$thumbs->installThumbsUp();
} /* Line 162 */
// When plugin is activated -> install.
register_activation_hook(__FILE__,'thumbs_install');
But when I activate the plugin I get the following error:
Plugin could not be activated because it triggered a fatal error.
Fatal error: Cannot redeclare thumbs_install() (previously declared in /dev/site/wp-content/plugins/thumbs-up/thumbs-up.php:160) in /dev/site/wp-content/plugins/thumbs-up/thumbs-up.php on line 162
I've googled and looked and it's talked about as a variable scope issue but I can't find any examples of the answer and my php is not strong enough to translate the discussion into code.
Here's the solution described by John Blackbourn in the WP-hackers ML:
Any global variables that you want to reference inside the function that is called by register_activation_hook() must be explicitly declared as global inside the main body of the plugin (ie. outside of this function). The plugin file is include()-ed inside another function at the point where it is activated unlike at others times when the plugin file is simply include()-ed. Phew. Bit of an odd one to get your head around but there we go.
I thought I had done what is described but I still get the error. I've also tried every other combination of where I could possibly put the global $thumbs...
There is a more generic answer to this question: every error that occurs in the code that is run from the function registered with register_activation_hook will be shown as "cannot redeclare ... " instead of the actual error. I suspect this is because of the way WordPress includes the plugin file when it calls the activation hook.
Note: if you arrived here via your search engine for a result about Wordpress's register_activation_hook() and global variables, please jump to the second part of this answer.
The rationale behind this error message is that the thumbs_install name is first created while include()ed once, and then a second time.
One of those times, it is include()ed in the scope of activate_plugin() from /wp-admin/includes/plugin.php on line 560; the other one is most likely your doing: Wordpress does not include any plugin that is not yet activated and includes the plugin file in activate_plugin() only once.
Moreover, I was unable to reproduce the issue with the code you pasted in your question, but I got exactly that error with the following version of the ThumbsUp class:
class ThumbsUp {
function installThumbsUp() {
include(__FILE__);
}
}
However, since you did not share the code of your ThumbsUp class with us, I cannot help you further on that direct matter.
It is worth noting that the first (before activation) inclusion of the plugin in the activate_plugin() function is aimed at preventing Wordpress from crashing because of un-activated plugins; and therefore, it is very well possible that the extra include() or require() happens somewhere else in the code of your plugin (not necessarily in a local scope).
About the use of global variables in the callback function passed to register_activation_hook(); essentially because the first include() (during activation) of the plugin happens in the scope of a function (activate_plugin()), it is necessary to declare those variables global in every location of the plugin where they are accessed.
That means: they need to be explicitly set global in the scope of the plugin file too (where you normally consider variables to already be global).
This is because the said variables are defined, during the first activation, in the scope of activate_plugin(), and unless set global explicitly, they will not exist in the global scope.
Example:
<?php
global $myvar;
$myvar = 'some value';
function using_myvar() {
global $myvar;
some_processing_with($myvar);
}
register_activation_hook(__FILE__, 'using_myvar');
Nota bene: Since after the first activation, the plugin is considered 'safe' to be include()ed globally; it is only necessary for variables used by the aforementioned callback to be declared global in the file scope.

Categories