Disadvantages of Wordpress - the technical side

    First of all, I consider it necessary to clarify several points:

    1. This article is not about any possible flaws in the admin panel interface, design themes, ready-made plugins for wordpress, or what else might a typical webmaster be interested in? With all this, in my opinion, WordPress is relatively okay. This article is about code.
    2. The article relies heavily on materials that I have gathered together, freely translated and from myself significantly supplemented. Links are provided at the end of the article.
    3. Popularity is not a synonym for quality. No need to use this argument as evidence of the quality of technical performance. WordPress is clearly popular for completely different reasons.

    Global variables are so cool, aren't they?

    Not. Global variables are bad and you should try to avoid them whenever possible. This statement is disclosed in detail in many other articles and is not something new or surprising for an experienced programmer. In short, global variables can be changed anywhere in the program, which can affect the operation of other parts of the program. For this reason, global variables have unlimited potential for creating mutual dependencies, which complicates the program. Global variables also make it difficult to integrate modules, because code written earlier can contain global variables with the same names as in the plug-in.

    So, WordPress uses them everywhere and for everything. For example, The Loop or Loopif in Russian. Using it, WordPress processes each post for output on the current page. It can be easily broken by the implementation of the following code:

    global $post;
    $post = null; 

    And try to guess where the global variable was declared or rewritten. It's hard to imagine how anyone could even have the idea that using such global variables is a damn good idea.

    Would a database abstraction layer be useful to a developer?

    Definitely yes. WordPress does not use the concept of models and any entities (well, there is WP_Post , but this is ridiculous). What about ORM and ActiveRecord? Forget it. All database work is organized using separate special objects for queries, such as WP_Query and WP_User_Query . In addition to them, there is an insane amount of inefficient logic to support pagination, filtering, sanitizing, establishing connections, etc. And to top it all off, every time a request is made, it changes the global object (see the previous paragraph). No, seriously, why should the database query result be stored globally?

    Developers also have access to functions such as query_posts()andget_posts(). The first is strictly not recommended for use in official documentation and in articles like this . And both are wrappers that call within themselves WP_Query.

    function query_posts($query) {
    	$GLOBALS['wp_query'] = new WP_Query();
    	return $GLOBALS['wp_query']->query($query);

    I also suggest that the reader try not to laugh and cry while reading the following illustration explaining WP_Query: All these problems would not have occurred if we had some adequate layer of database abstraction under the hood. WordPress has a global object (yes, again)  wpdb  that tries to emulate an abstraction layer. Tries. Another important point - WordPress does not imply that the developer may want to create arbitrary tables in the database for their needs. For some reason, you need to store all the data only in predefined tables. The following is a WordPress database schema version 3.8:


    WordPress relies heavily on the essence of post and the types of these posts. Here we can trace the legacy of WordPress as originally a blog-only engine. By default, we have the following list of post types:
    • post - blog post, post
    • page - page
    • attachment - a media file (that is, an image uploaded and attached to a post using the "Add media file" button, in WP terminology this is also a post in turn)
    • revision - different editions of the same post
    • nav_menu_item - menu item (yeah, that means the link in the menu is also a post, great)

    If you make a plugin and you need to declare your own entity, for example, “completed project”, you register a new post type. This feature has appeared since version 3.0 and is called custom post types .

    So, all this should be stored in one single database table and its name is posts. We also have a postmeta table. It’s easy to guess that you need to store all the meta information related to posts there. The options table suggests storing different settings for WordPress itself and all installed plugins. As a result, sooner or later we will get bloated tables, the search or sorting by which can be a problem.

    Theoretically, a developer can create his own arbitrary tables in the database, but WordPress will not know anything about them and will not be able to organize any interface for managing the data stored in such a table. All that remains for the developer is PDO and MySQL queries.

    Creating custom post types and taxonomies for everything is not a solution to the problem, this is the problem.

    Routing with mod_rewrite

    This in itself is not bad. It’s bad to change the mod_rewrite rules by updating the .htaccessfile when the kernel or any plug-in adds or redefines the routing rules and only when you click on the update settings button on the routing settings page in the admin panel (a headache when debugging).

    In the world, such routing approaches as, for example, Symfony , have been invented, widely known and widely used for a long time  . Most, if not all, WordPress routing problems could be resolved using a PHP-level router. All of these "useful" functions like is_page(), is_single()and is_category() would have been unnecessary, since the router would be responsible for all mapping and scoping.

    To understand how sad everything is, I suggest a look at the  corresponding page of the documentation .

    What about file architecture?

    The first WordPress release took place on May 27, 2003, over 11 years ago (imagine). MVC architecture was not yet widely known and used then; accordingly, WordPress is simply divided into many separate files arranged in certain directories, in the usual way for the PHP developer of that time. This approach is reflected in the design templates, in which pages with specific roles have the corresponding PHP files: index.php, archive.php, single.php, etc. - instead of using sensible routing (see paragraph above). Yes, this is the whole legacy from time immemorial, but from this it does not cease to be a problem now. If you have enough free time, you can see the  video of the report, which illustrates what issues professional WordPress developers face today. There, a man 40 minutes tells how he organized the architecture of the design so that it was, let’s say, somewhat more convenient. Cool, but why does he even have to do this and then talk about it at the conference?

    And here is a small and not very significant detail, but every time my sense of beauty makes me suffer. The name of the design template and other meta information about it are stored in the style.css file in the root directory of the template. Styles are also usually stored there. What if we want to use scss, use a collector that minifies, concatenates and puts all the css code somewhere in the app.css file in the build folder? Ok, but we still don’t get rid of style.css in the root directory. WordPress is tied to the template name stored in this file. There may not be a single line of css, but there should be a line with the name of the template. If you delete or rename this file, everything will break.

    Let's move from the architecture of the templates to the rest of the code base. Most of the functionality is provided through global functions (this is bad, see the point above) and is not encapsulated in classes / not organized through namespaces. I will not describe why this would be good - this is a widespread and well-known approach. It comes to the point that the creators of any significant plugins organize their own mvc architecture with preference and young ladies within the directory of their plugin.

    Any standard WordPress class or function can be found in the wp-includes directory in one of the many files, which certainly serves as some kind of code organization. At least they tried.

    Although architecture is not so good, at least templating works well

    WordPress templating? No, no template engines are used. You can argue, because PHP itself is a template engine, and in general was originally conceived as a template language. Well, this is true, but it is not used here in the same way as template engines usually use. I mean that there are no layouts, reused parts (partials), automatic shielding, etc. etc.

    WordPress has been around for over 11 years. Smarty for over 12 years. Twig for over 4 years. I don’t see a single reason why it was impossible to use a third-party library or even come up with something of my own. The fact that the templates have to use all of these  get_header(), get_sidebar()and  get_footer() - miserable.

    The action and filter mechanism of hooks is quite powerful and convenient.

    Let's not pay attention to the fact that in fact all these actions and filters are almost the same thing, only they are called differently.

    function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
    	return add_filter($tag, $function_to_add, $priority, $accepted_args);

    Let's also close our eyes to the fact that the principle of operation of all these actions and filters has long been known to the world, and the name has long been invented - events, events. Only unfinished, for example, the process of “surfacing” events cannot be stopped.

    In WordPress, this hook mechanism is used, like global variables, everywhere and for everything. The whole system is built in such a way that as the code executes, certain events occur on which certain functions are hung. You can say that this is cool, because the developer can redefine the behavior of the system in any way, without the need to make changes directly to the kernel. Yes, any plugin or design theme can carry hooks that change any data, redefine logic and, at the same time, cause problems later as the code continues to execute. Another feature is that the number of arguments passed to event handlers is truncated to one by default, unless explicitly stated otherwise (referring to $accepted_argsabove in the code). In which case, may I even need this and I do not want to get all the arguments?

    Both of these points sometimes lead to a nightmare during the debugging process.

    What about error handling?

    Instead of using the standard error and exception handling mechanism built into PHP, WordPress uses its own bike. Receive, sign. Instead of throwing exceptions and giving the developer the opportunity to catch them and how to handle them, WordPress returns (namely return, not throw) an instance of the class  WP_Errorcontaining a message and an error code, you know, just like an exception.

    Which makes the situation even funnier - some functions accept an argument that allows you to choose what it will return on error -  WP_Erroror false. No comments.

    But WordPress has tons of cool plugins and design templates!

    Take everything that has been listed up to this point, add everything that will be listed, then multiply by two. Here's what ready-made third-party plugins and templates are all about. You will be met: poor and inconsistent architecture between various plugins, abuse of actions and filters, inefficient work with the database, and generally low-quality code.

    For me, the most interesting thing here is that in case of any problems related to the behavior of WordPress itself or one of the already installed plugins, the user usually thinks that installing another plugin will solve the problem.

    Oh yes. With each newly installed plugin, you also increase the chance of such a development of events: " Critical vulnerability in the popular FancyBox for WordPress plugin". A plugin with over 500,000 downloads. Anyone could just send an anonymous POST request in a certain way to WordPress, thereby changing the options of the vulnerable plugin as desired, including the option to display additional content. XSS is ready.

    Code Writing Standards

    Instead of supporting the rest of the PHP world in the use of PSR or PEAR standards , WordPress developers decided to write their own standard , which is in many ways the opposite of the above.

    Pseudo Cron Tasks

    Instead of using a real cron scheduler, for WordPress they created their own, working at the level of PHP. It saves links to callbacks in the database, and then with the help of PHP starts them on certain events. Of course, it does not work all the time in the background, as you might think. Every time someone visits the site, the cron tasks are checked and if it is time for some of them, then it is executed. Maybe a minute later, maybe a few hours.

    As a result, you can find a bunch of notes on how to disable wp_cron and connect the real one. And yet these:  Why WP-Cron sucks . There is already about the negative impact of WP-Cron on the speed of highly loaded sites.

    Image slicing

    When you upload an image to your media library, WordPress cuts it into different sizes. By default, 3 sizes are hardcoded: miniature (150x150), medium size (300x300), large size (1024x1024). In the control panel, you can change the width and height of each of these sizes, but not delete or add a new size. To add size you need to get into the code and use the add_image_size () function  .

    Imagine that we installed a theme, the developer of which added the following code to the functions.php theme file, which suggests describing additional functions for the theme to work and setting WordPress core parameters:

    add_action( 'after_setup_theme', 'foo_theme_setup' );
    function foo_theme_setup() {
      add_image_size( 'category-thumb', 400, 400, true );
      add_image_size( 'homepage-thumb', 220, 180, true );

    Now upload, for example, a photo of foobar.jpg with a size of 1600x1600. Regardless of your desire and without giving any choice, WordPress will create the following files in the wp-uploads directory: foobar.jpg (original uploaded file), foobar-150x150.jpg, foobar-300x300.jpg, foobar-1024x1024.jpg , foobar-400x400.jpg, foobar-220x180.jpg. That is, in our case, 6 files per 1 uploaded image, even if you just wanted to insert the original image on the page and you do not need the rest of the slicing. When we upload another 300 images, the files will already be 1800, most of which will never be used and will simply be dead weight on the hard drive. And if we still have plugins installed, which also add their size? How many files will then be created per image?

    If we want to change the design theme to a new one that already sets its own, other sizes and involves the use of them, then everything will break. After all, previously uploaded images are already sliced ​​differently. In this case, it is proposed to solve the problem using a third-party plug-in, for example  Regenerate Thumbnails , which will delete all the old slices and from the original images stored will make a new one according to updated rules. Why such a generally simple and quite important functionality is not built into WordPress itself is a mystery to me.


    It may seem that I hate WordPress. Not at all. I have been dealing with this CMS since 2. * versions, approximately since 2009, with its help I have been able to create more than a dozen sites over the past time, I am grateful for this. We are actively using WordPress in the studio where I am working now and it is unlikely that we will soon be able to replace it with something more effective, although we are watching with interest the development of October CMS (CMS based on the PHP Laravel framework) and fantasize about migration after the release of stable version.

    The w3techs website  provides the following statistics  for January 2015 - 23% of the sites from the top 10 million websites ranked by Alexa ranked WordPress. The share among other CMS in this sample is 60%. Next comes Joomla with 7.5%, the gap is huge. Where does this popularity come from? Why did I choose WordPress at the time and a huge number of other people? Apparently, the great friendliness of the site management interface, the simplicity of installation and use, all these thousands of ready-made plug-ins and templates, the low entry threshold in order to, excuse me, novnokodit something of their own. These qualities correspond to everything that is so important for a typical webmaster or a person who just needs his blog with photos of cats. To people who are not close engineers and do not want to hear anything about any architectures, hooks, etc.

    Do not forget the wordpress.com service  , allowing you to quickly create a site based on WordPress, without worrying about buying a hosting and installing CMS yourself. Serves more than 60 million sites. The service was created in 2005 by Automattic, which makes a huge contribution to the development of WordPress. And, it seems to me, this is directly related to the fact that the news about the upcoming WordPress update indicates such things as a new theme, improvements in the text interface, convenient image alignment, a new “recommended plugins” tab and other tinsel. This is what the target audience needs. And in the section for developers it is written that a bunch of bugs have been fixed. And no hint of a global improvement. This can be understood, you can’t just take it and refactor everything, and, again, the target audience does not need this.

    In conclusion, I will quote from  an interview with Alexei Bobkov , the developer of October CMS. A quote that, in my opinion, very accurately describes the situation with WordPress:
    What CMS did you work with before and why did you decide to write your own CMS?
    I had to work with different CMS. The interface of many CMSs looks so bad that they give up on working with them. I do not like to scold other people's products, so I will not list the names, except for one. WordPress is not bad, but it’s already seen that this is an old school app. Even the best (popular) plugins for him are pure spaghetti from PHP code and different files. It takes a lot of time and some special knowledge to figure out what’s happening and fix it, for which you need to shovel forums and blogs where people mostly ask the same questions and don’t get clear answers.
    I would like to have something simple and flexible, a real platform for developing sites and applications, with a beautiful interface and a thoughtful approach to extensibility. Something that can be described in several pages of documentation and so that people who use it can spend time on more pleasant things than solving simple problems in a complicated way.

    Related links:

    Also popular now: