[Discuss] PSR2 Line Length and Long String Arguments

Here’s a question for you, community.

When respecting PSR2’s line length rule, you’ll often need to pass long strings into methods as arguments. For example, during unit testing with PHPUnit, you might need to pass a lengthy explanation into $this->fail().

In these cases, do you opt for

  1. Heredoc / Nowdoc
  2. Concatenation
  3. Something else?


I mainly use Heredoc for things that use indentation like SQL queries, HTML snippets, email templates, or XML documents. Otherwise I use multiline strings.

The PSR2’s line length rule is a soft rule, so your question is indeed valid since the situation is not entirely covered in the conventions. Strings are usually output data. Other sane cases I could think of are file paths or identifiers such as hash/dictionary keys. In the case of file paths, the string can usually be stored in a configuration file, which isolates the problem and can IMO break the soft rule. In the other case (identifiers), the string is relatively short and shouldn’t cause any problems. Also most identifiers can be defined as constants and a define instruction is short enough to allow a reasonable string length for the value.

Now in the general case, where strings are used for output one might think of the principle of separation of concerns. For instance, you’ll try to avoid mixing PHP code with HTML code by collecting all view data and doing trivial prints in a (by convention) *.phtml file. Here the problem is intentionally reversed: the file itself is a huge string and you try to limit the size of your dynamic output instructions. So when thinking of strings as output data, you might want to consider putting them in separate resource files or a database.

An example might be validation error messages or any type of pop-up message that is generated at the server side. In this case I would create a key-value store for string resources, from which I could fetch the template string (using perhaps a short string key). Then the actual string never appears in PHP code and can be finalized using a sprintf-instruction.

Another example is an SQL query. Some existing frameworks (not only in PHP) have introduced the concept of named queries. This actually falls back to the previous example in which a separate resource contains all query statement templates (we all use parameterized queries, so this will suit perfectly ;)). These templates can then again be fetched using a short name (key).

Applying these techniques, heavily based on SoC will also bring the advantages of the principle: all string resources are centralized and are very easy to manage. You could even extend the mechanism to support internationalization or multiple SQL vendor queries: even though PDO offers many drivers, it still doesn’t abstract the actual query language. If you want that, you’ll need Doctrine (DQL) or another variant.


Actually most of my teams are tend to ignore any standards in tests, because readability is the key factor in tests.

And I, by my self, do not see any reason to follow “any” (of course we are following them when-ever it is possible and makes any sense) coding standards in tests.

We usually add <directory>../src/*/*Bundle/Tests</directory> to our phpunit.xml in Symfony projects

@Mantas of course, that was just an example. There are other cases where you need to pass long strings into methods, too.

@dennisdegryse thanks for the input, a very good reply. I agree on most parts.

I mainly use PhpSpec instead of PHPUnit and by definition I don’t use PSR2 in Specifications. I check PSR2 in src folder only, not in spec folder.

On other hand if in production code I found this problem I refactor code: introduce variable, use sprintf. When I must write long SQL I use multiline strings, but it’s rare when you use kind of Query Builders.

From time to time I have long line of code in production code. If this cannot be easily changed it’s ok for me. PHP CS is just tool. I and my Team decide if we can ship code or not, tools only help us make decision.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.