Why PHP is bad and why it isn’t

Nowadays programmers consider PHP as a very bad programming language. One of the example is in this comic strip, saving the princess with programming language. But why is PHP considered bad and why does it is very popular out there?

The good

In general, PHP is a good language to start learning programming with.

It’s easy to setup and start

PHP is very easy to setup, especially for beginner. Just use XAMPP (for windows) and LAMP (for linux), and drop the code in htdocs and everything will go well. Just search in google for “hello world php xampp” or “hello world php lamp” and you’re good to go.

Furthermore it’s one of the easiest language to setup shared hosting, making it very easy to make your own website.

It’s very forgivable

PHP is dynamic typing, meaning you don’t need to specify whether an variable is string, int, specific class, etc. And it’s string concatenation is different with numeric additional, making it less ambiguous than javascript’s dynamic and don’t need type conversion. It’s very easy for beginner to start with.

And PHP variables works very well with HTML. Almost all native variables can be printed to screen by using echo, while array and object need special treatment.

Furthermore, using undefined variable only resulting in notice, and can be easily suppressed. But beware, both are considered “bad habit” in programming, so take it as learning features. There are also more exceptions that usually result in error in other language, that can easily suppressed in PHP.

It’s both procedural and OOP

PHP can serve procedural code, and OOP one. It’s very common to start learning programming with procedural, and learning OOP next, and it’s easier in same language.

Furthermore, PHP is a C-like syntax programming language, and there are many good languages in C-like syntax, like Java, C# and javascript. It’s C-like syntax is better than python (which is also a good starting language) “if” you aim to move later to those language.

Frameworks and tutorials are abundant

With many framework and tutorials out there, someone can search any problem or topics that they currently worked at, and finding many pages of google results. It’s very easy to find answers to PHP problems nowadays.

Furthermore, many PHP framework are using MVC (Model View Controller) pattern, which is one of the most common pattern in web programming. Learning them can help transition to other good languages using MVC pattern, such as Java MVC spring, C# Asp.Net MVC, NodeJs MVC frameworks and many more.

Furthermore nowadays PHP has composer, which is good to handle library as packages, which is almost all new languages use. And PHP has many CMS which make creating webpage like wordpress CMS easy.

The bad

So why is PHP considered bad? Well you need to at least good in programming to know it’s limitation and bad side.

It is not strong, static typed

PHP starts as dynamic, weakly typing language, helping to customize HTML pages ages ago. Up to this day, it still support dynamic typing, while supporting some type hinting at arguments and property level. While dynamic typing is good to start learning programming, it’s not good at complex business process.

However, being interpret language means the type hinting can only trigger when executed. So we won’t get any type error up until the portion of code is executed, as opposed to Java/C# where it can be caught compile time.

Moreover, PHP7, even after getting scalar type hinting for string and int, still not having generics for array. Without any means to type checking array, it’s harder to do type checking and enforce reliability, especially in business process (accounting).

It doesn’t have multithreading options by native

Without using additional components “PThreads”, PHP doesn’t have any options to emulate multithreading. It isn’t that PHP cannot do multithreading, however the problem lies in how “PThreads” works. It copy the current “process” state (loaded classes, etc) into another process and execute them concurrently.

In my experience with PThreads for PHP 5.6, (maybe I just lack configuration, correct me if so) PThreads use bigger memory than other programming languages, notably C#, Java and NodeJs. Moreover it’s harder to catch exception and to debug process spawned by threads.

So it doesn’t support multi-core process

In case of heavy background process or batch processing, most of the time multi-core support is a requirement.

It doesn’t have memory-persistence cache

PHP is run-and-forget scripting language, which load all it’s needed reference class on beginning of request (and during execution for lazy loading one), and to flush them later. The process takes time, and while PHP7 doing JIT to cache some of it’s code, it’s still not efficient because they need to be loaded for every request.

In contrast with PHP’s scripting, NodeJs and C# Asp.Net MVC (haven’t use java, but should be similar) run a server, and keeping the loaded classes (scripts) in memory, making them more efficient.

It’s dynamic typing takes too much memory

Looks like it’s mitigated in PHP 7, however in PHP 5.6 below, the dynamic variable in PHP takes too much memory. It’ll soon be a hassle when working with big variables, big file or many records of data.

And even if PHP7 is more efficient, it still can’t beat C/C++ level of memory usage per variable. And arguably, so do as in comparison with static typed language, such as Java and C# and the currently rising golang.

It’s data access doesn’t support multiple-result sets

Apply for MySql at least (looks like it supported in PostgreSQL). PHP cannot return multiple tables in one query. Let’s say that you have one procedure that returns 3 select queries, PHP MySql driver can only return one.

Many of it’s library support is configured at installation level

Some of the native library for PHP is configured during installation (gcc make and phpize). Some of the examples are zip (–enable-zip), thread safety (–enable-zts) for pthreads. It makes binding configuration to app repository level harder and reduce portability.

In conclusion

PHP is a good language to start programming with, easy to setup and have many libraries / framework / CMS. However in case of advanced use by expert programmers, PHP doesn’t really meet up the requirement.


Microsoft SQL Server : What you need to know as beginner developer?

I realized that Microsoft SQL server is easy to use and setup. It’s UI (management studio) is easy to use, user friendly and nice. However, used by beginner developer, usually the SQL Server will perform bad. As a beginner at MS SQL Server world, what do you need to know?

In this series, I will provides hints and small description about what topics you need to learn beforehand. If you need detailed explanation, you need to do detailed research yourself.

Database transaction isolation level and lock hints

This is the very first thing that you need to know when developing system with SQL Server as database. Why? Because not knowing this will grant you over 80% possibility of deadlock when used in high-transaction system.

By default, MS SQL Server use Serializable isolation level for read queries (select). It is the heaviest-locking isolation level that you can achieve with SQL Server. The most secure, but also the most problematic. It basically locks the table (or page) every time you do select/insert/update/delete queries. In heavy read and light write applications such as stackoverflow, this usually cause problems.

Microsoft recommend Read Committed Snapshot Isolation (RCSI) level for common system. But still you need to search for yourself the best isolation level that is most suit with your apps.

Auto-commit transaction

By default, MS SQL enables the auto commit feature, means that every insert/update/delete that is not inside a transaction will be wrapped in a transaction and committed. This is bad for performance, because every commit will add record into your database log and it hurts performance. This is especially happen in looped-generated statement (to insert/update/delete many rows from applications).

Basically to avoid this, you need to wrap your statements in a transactions, or set auto commit off.

Backup Recovery Model

By default, MS SQL has backup recovery model set to FULL. In contrast to SIMPLE recovery model, full recovery model enables you to point-in-time recovery per transaction committed. While in simple model it is not supported. In short, set to simple model if you don’t think that point-in-time recovery is required, especially in logging database.


Indexing is complex, but in case you need to maintain database performance against big volume data, you need to learn indexing. First, you need to know how to get the query execution plan. Next, you need to know the index seek vs index scan, key lookup, and sargable query.

In short, what I recommend is:

* Always use primary keys in all your tables,

* If you need to do join query, ordered by recommendation, it’s better if you can:
1) join between primary key/foreign key
2) the joining field contains same data type and length
3) avoid computational at where clause or joining fields, eg: isnull, where fieldA < fieldB + 1
4) do not use leading wildcard (percent) in string search

Connection overhead

Opening connection and user authentication is providing some performance impact. It is not much, but exists, especially when the application server is far away from database server. Please note that stating there is connection overhead does not means that keeping the connection open is the solution. What you need to avoid is opening/closing connection inside an application loop. It’s better to re-factor it to become more like set-based operation.

Scalar vs table-valued function

In MS SQL, there are 3 types of functions, that is scalar function, table valued function and multi-statement table-valued function. Execution plan wise, scalar and multi-statement table valued is same, while table-valued function is operated more like accessing view. So let’s consider multi-statement table valued function the same as scalar in this topic.

Scalar function inside select column / join / where clause will be converted in looping operations. Meanwhile table-valued function will be treated the same as view, and then being included in query plan as set operations. So, in short, if the function you defined is accessing any table, avoid define it in scalar function.


SQL Server, after being installed can be easily used. But not knowing the features of SQL Server and then using it to make complex system can cause problems. Before actually using it in real system, I suggest that you at least know the points I described above.

However, even if I know those points, it does not immediately makes me know all the SQL Server and the best configurations for each scenarios. I am not a database administrator after all.

Why I avoid ORM in my enterprise architecture

Yesterday I have a nice, interesting chat with someone I just met. In those discussion about software development and technology, he asks whether I use Entity Framework for my current architecture or not. I was saying it clearly, I’m not using any kind of ORM nor develop one myself. Before I continue, I want to clarify that I’m not hating the ORM or anything. With my current skill and experience, I’m just not ready for the edge cases (or to be precise, corner cases) that can occur when using ORM.

When asked with such question, I had hard time to give reasons about it. One of the reason is that there will be hard to find developer with expert knowledge of particular ORM, rather than expert knowledge in stored procedure-based command execution. The other is, ORM has leaky abstraction. I’m not saying that other than ORM or any tools that I used until now has none leaky abstraction, but I don’t think it’s worth the effort to do the workaround for ORM’s corner cases, compared to matured, traditional stored procedure and query.

Not all Linq expression is supported to be translated into sql

This statement is primarily based on article from Mark Seeman: IQueryable is a leaky abstraction. In that article, he state that there are some unsupported expression exposed from IQueryable. He states that the unsupported expression itself violates LSP. Moreover, quick search at google shows some stackoverflow questions asking for the NotSupportedException. One of them shows inconsistency with linq2sql, where when someone use string.Contains the ORM throws exception meanwhile using join the expression executed. Another post says the same about EF.

So as we can see, the IQueryable interface used by ORM give us false guarantee or false positive, just because the code compiles but produce runtime exception later. The same case can also happen with SqlCommand. However the error is clear, that it’s either: 1) different sql data type provided to SqlParameter, 2) incorrect parameter provided, 3) wrong sql syntax. However it is the opposite with in-memory IEnumerable lambda/linq, where the expression is fully supported.

Now we have additional step to measure sql performance

ORM translate query expression into sql queries. If you do not master the specific ORM, you won’t know what kind of sql query produced. Moreover, different ORM produced different query. Now if we concern about the sql performance, we have 2 steps to do. First step is to determine which exactly sql query resulted from ORM, while the other is real measurement with indexes, plan, etc.

Common case is N+1 selects issue with ORM in which handled differently by different ORM, and impact the performance.

Data annotation breaks POCO and SRP

This is specific to EF with data annotation. If you prefer to use fluent api, great on you.

Data annotation break POCO, nuff said. Based on wikipedia, POCO or Plain Old CLR Object is simple object which does not have any dependency to other framework/plugin/tools. Even Serializable and XmlIgnore data annotation breaks POCO, and I’ve already stated that cluttering the class to make it xml serializable is usually bad.

It also breaks SRP. Now that your POCO class has another responsible coupled with it. The additional responsible is handling the way ORM mapping from table to the object. It isn’t wrong, but it’s not clean. The worst part is, you need to modify your POCO class to meet mapping requirement.

The original underlying structure of database is relational

Original post by Martin Fowler states that the root of main problem is the difference in underlying structure between application (OOP) and database (RDBMS). The way they handle relations is different and the way they are processing data is also different. Even Jeff Atwood also said that the ORM problem will be clear by either you remove the “object” aspect or “relational” aspect, either by following table structure in application or using ODBMS. ODBMS is great, but it also has cons compared to RDBMS.

When and how many times the query being executed?

I don’t know how good you are with IQueryable abstraction. However even with in memory IEnumerable, there are many times i’ve caught with bug where the iterator is executed multiple times, resulting in inconsistent data properties and increasing cost. With IEnumerable / IQueryable ORM, I don’t know when and how many times exactly the sql query being executed, and it can impact performance considerably.

Additional sources where they have documented the issue

These sources are more like general statements or even the detailed technical one, so I don’t follow it one by one. But it shows you the lists of current problem faced by ORM.


As a developer / architect that concern with clean code, consistency, coding standard and convention, I don’t think that ORM will suit me. There is simply too many corner cases that can’t be handled by current ORM, and I don’t like (and don’t have time) to document every cases that cannot be handled, and the solution or workaround. It’ll be a pain to teach to the new developer your ORM case handling standard. Moreover it can cause you more time to fix the problem caused by the ORM rather than it’s benefit.

However if you find yourself confident that you can handle the corner cases, or if you exactly know that the application won’t face those corner case with ORM, then it’s a great tool to be used.