Nette Utils 4.0: UTF-8, Finder and named arguments

11 months ago by David Grudl  

We are pleased to announce the release of Nette Utils 4.0! This update brings many new features and a shift in programming style, which we will now present in detail. At the same time, it should be fully compatible with the previous version, besides removing a few deprecated features and modifications to the Finder.

Finder

Finder is now part of Utils 4.0. This move was logical, since the Nette\Utils\Finder class belongs here by namespace. If you were using nette/finder in Composer, you can now remove it.

At the same time, the Finder has been rewritten from the ground up and brings a number of new features, which are the subject of a separate article.

Flags vs named arguments

Nette Utils improves the programming style by replacing flags with named arguments.

What are these flags? They are constants used to specify the behavior of a function:

Json::encode($value, Json::PRETTY | Json::ESCAPE_UNICODE);

One of their disadvantages is that it is not clear from the API what flags can be used in which function. For example, you may wonder if Json::FORCE_ARRAY can be used with Json::encode() or decode()? Also, with each flag, you need to repeat the class name in the code.

Nette Utils 4.0 therefore replaces them with named arguments, which do not have these drawbacks:

Json::encode([1, 2, 3], pretty: true, asciiSafe: true)

This change is completely backwards compatible, which means that the original code still works. But it is not preferred.

The switch to named arguments applies to the following methods and flags:

  • Json::encode(): Json::PRETTYpretty, Json::ESCAPE_UNICODE → asciiSafe
  • Json::decode(): Json::FORCE_ARRAYforceArrays
  • Arrays::grep(): PREG_GREP_INVERTinvert
  • Image::resize(): Image::SHRINK_ONLYshrinkOnly
  • Strings::split(), match(), matchAll():
    • PREG_SPLIT_NO_EMPTYskipEmpty
    • PREG_OFFSET_CAPTUREcaptureOffset
    • PREG_UNMATCHED_AS_NULLunmatchedAsNull
    • PREG_PATTERN_ORDERpatternOrder

The Json::ESCAPE_UNICODE constant is changed to asciiSafe, which better describes its meaning (i.e. that the output should be in the ASCII range) and is consistent with the newly added htmlSafe parameter.

Regular Expressions in UTF-8 mode

Improved support for UTF-8 mode for regular expressions in Nette Utils 4.0 will make it easier for you to work with multilingual content.

All methods of the Strings class for working with regular expressions, i.e. split(), match(), matchAll() and replace(), have a new $utf8 parameter that switches the operation to UTF-8 mode. It also affects the input parameter $offset and the output offset values when captureOffset is used. These values will then not be in bytes, but in characters, which makes further manipulation of the text easier:

Strings::matchAll(
	'žluťoučký kůň',
	'~\w+~',   // \w matches also characters with diacritics
	utf8: true,
	offset: 2, // starting from the character 'u'
	captureOffset: true,
);

/*
array (2)
   0 => array (1)
   |  0 => array (2)
   |  |  0 => 'uťoučký'
   |  |  1 => 2 // position 2nd character
   1 => array (1)
   |  0 => array (2)
   |  |  0 => 'kůň'
   |  |  1 => 10 // position 10. character
*/

More news

Several new methods are available:

  • Nette\Utils\FileSystem::unixSlashes() converts slashes to Unix slashes
  • Nette\Utils\FileSystem::platformSlashes() converts slashes to system slashes, i.e. \ on Windows
  • Nette\Utils\Strings::ord() function ord() for UTF-8
  • Nette\Utils\Helpers::compare() comparison using the operator

New parameters added:

  • Json::encode(): parameters $htmlSafe and $forceObjects
  • Strings::split(): parameter $limit
  • Strings::replace() parameters $captureOffset and $unmatchedAsNull

The Nette\Localization\Translate interface has been extended (see diff) and this change is backwards compatible.

Removed stuff

The class Nette\Utils\Reflection provided methods getParameterType(), getPropertyType() and getReturnType() for working with the types. The methods were created when PHP didn't have union, intersection or the latest disjunctive normal form types, which they no longer work with and have been replaced by the Type class. As of version 4.0, these methods have been dropped. The Nette\Utils\Reflection::getParameterDefaultValue() method is deprecated, since the native ReflectionParameter::getDefaultValue() method already works correctly.

The Nette\Utils\Html::$xhtml variable is deprecated.

Installation

To install Nette Utils 4.0 you need to update RobotLoader to version 4 if you are using it, and remove the nette/finder package:

composer remove nette/finder
composer require "nette/utils:^4.0"  "nette/robot-loader:^4.0"