Nette Utils

repository·master·Indexed 24 days ago

https://github.com/nette/utils

A comprehensive collection of utility classes for PHP development, providing tools for filesystem management, string manipulation, HTML generation, data validation, and process execution. Includes specialized APIs for arrays, iterables, JSON encoding/decoding, image processing, and a recursive file finder. Compatible with PHP 8.2 through 8.5.

Tokens
9K
Snippets
2
Records
74
Agent score
74%

What's inside nette-utils

  1. Overview of Nette Utils capabilities

    master

    Nette Utils is a collection of utility classes designed for common PHP development tasks. Key features include:

    • Data Handling: Arrays, JSON encoding/decoding, Iterables, and Floats.
    • Filesystem & Search: Filesystem operations (copying, renaming, etc.) and Finder for locating files and directories.
    • Text & Strings: String manipulation, generating random strings, and Helper Functions.
    • Web & UI: HTML element generation, Image processing (crop, resize, rotate), and Paginator for pagination math.
    • Logic & Validation: Callback handling, Validation of inputs, and Type checking.
    • Advanced PHP: PHP Reflection and SmartObject for object enhancements.
  2. Html: Attribute setters and method collisions

    master

    The Html class uses magic methods (__set, __call) to manage attributes. You can set attributes using several syntaxes:

    $el->href('x');
    $el->href = 'x';
    $el->setHref('x');

    Important Traps

    • Method Collisions: Some names are real methods, not attribute setters. For example, $el->setText(...) calls the setText method, whereas $el->setTitle(...) sets the title attribute. Other real methods include setHtml and setName.
    • Nameless Elements: Html::el(null) creates an element that renders only its children without surrounding tags.
    • Escaping: Html::fragment(...$children) and $el->add(...$children) escape plain strings by default. To pass raw HTML, use HtmlStringable objects or addHtml().
    • Factories: Html::text() and Html::html() are static factories for escaped text and raw HTML respectively.
  3. DateTime: Mutability warning

    master
    The Nette\Utils\DateTime class extends the native mutable \DateTime. Methods like modify() and setters change the instance in place. Do not pass a DateTime instance around assuming it behaves like a value object (immutable).
  4. Image: Transparency scale differences

    master

    When working with the Image class (which requires ext-gd), be aware that transparency is represented using two different scales depending on the object type:

    • ImageColor object: Uses an opacity scale of 0 to 1.
    • Legacy GD array: Uses an alpha scale of 0 to 127.

    These scales are inverted relative to each other.

  5. FileSystem: Destructive defaults and error handling

    master

    The FileSystem class prioritizes convenience over caution, which can lead to accidental data loss:

    • Overwriting: copy() and rename() overwrite existing files by default ($overwrite = true). Pass false to enable protection.
    • Directory Copying: Copying a directory over an existing one replaces the target (deletes current contents) rather than merging.
    • Deletion: delete() is recursive on directories and succeeds silently if the path does not exist.
    • Auto-creation: write(), copy(), and rename() automatically create missing parent directories.
    • Errors: All failures throw an IOException; the class never returns false.
  6. Execute processes safely with Process::runExecutable() vs Process::runCommand()

    master

    The Process subsystem provides two distinct ways to start a process, which behave differently regarding shell involvement:

    • runExecutable(): Accepts an argv array. The shell is never involved. This is the safest method as it avoids shell escaping issues and prevents command injection. Use this when you have a specific executable and its arguments.
    • runCommand(): Accepts a single command string. This string is handed directly to the system shell (/bin/sh on POSIX or cmd.exe on Windows). Never pass unescaped user input to this method, as it is vulnerable to shell injection.

    Always prefer runExecutable() for security when handling dynamic arguments.

  7. Manage Process lifecycle and timeouts

    master

    When working with the Process subsystem, be aware of these lifecycle behaviors:

    • Timeouts: The default $timeout is 60 seconds. This timeout is enforced during blocking operations like wait() or consume*(). If the timeout expires, the process is terminated and a ProcessTimeoutException is thrown.
    • Destruction: If the last reference to a Process object is dropped (e.g., the variable goes out of scope), the __destruct method will automatically kill the still-running child process.
    • Termination: The terminate() method is designed to be untrappable. On POSIX systems, it sends a SIGKILL, and on Windows, it uses taskkill /F /T. This ensures that the subsequent proc_close() call cannot hang.
  8. Difference between Arrays and Iterables

    master

    The nette/utils library provides two parallel APIs for collection manipulation. Choosing the wrong one can lead to empty results during iteration.

    • Arrays::*: Operates on native PHP arrays. These methods are eager and always return a re-usable array.
    • Iterables::*: Operates on any iterable. These methods are lazy and often return a Generator.

    The Trap: A Generator returned by Iterables::* is single-use and non-rewindable. If you attempt to iterate over the result a second time, the second pass will be empty. If you need a value that can be traversed multiple times, use Arrays or wrap your iterable with Iterables::memoize().

  9. How Finder works: Search patterns and recursion

    master

    The Finder class uses an emergent two-stage model to resolve file paths. It combines native glob() for fixed prefixes with manual directory traversal for recursive patterns.

    Key Search Behaviors

    • Recursion: The ** wildcard triggers recursive searching.
      • test/** is expanded to test/**/*.
      • **.c is expanded to **/*.c.
      • from('dir') is a shortcut for in('dir/**').
    • Directory Filtering: A trailing slash in a mask (e.g., find('test/**/')) restricts results to directories only. Using a trailing slash in findFiles() will result in an error.
    • Anchoring: A ./ prefix anchors the pattern to the search root (^). Without it, patterns match at any segment boundary.
    • Case Sensitivity: Case sensitivity is platform-dependent. On Windows, the i flag is automatically added.
    • Exclusions: The exclude() method uses the same grammar as the search mask.
      • exclude('dir'): Excludes the entry anywhere.
      • exclude('dir/'): Excludes directories only (and their contents).
      • exclude('dir/*'): Excludes contents but keeps the directory itself.

    Implementation Details

    • Paths: Paths are kept native. On Windows, output may mix separators. Do not attempt to manually normalize paths as it can corrupt valid POSIX filenames or protocol strings.
    • Filters: Finder distinguishes between descentFilters (decide if traversal enters a subdirectory) and filters (decide if an entry is yielded).
  10. String manipulation requirements and UTF-8 assumptions

    master

    The Strings class assumes valid UTF-8 input. It relies on various PHP extensions, and behavior varies depending on whether they are installed:

    Hard Requirements (Fatal if missing)

    • lower / upper / compare: Requires mbstring.
    • toAscii / webalize: Requires intl (otherwise throws NotSupportedException).
    • chr / ord / reverse: Requires iconv.

    Graceful Degradation

    • normalize / compare: If intl's Normalizer is missing, NFC normalization is skipped.
    • length / substring: Falls back through mbstring to iconv.

    Regex Behavior

    All regex APIs (match, matchAll, replace, split) use Strings::pcre(). Unlike native PHP functions that return false on failure, Strings converts all PCRE failures (compile-time or run-time) into a RegexpException. This includes failures caused by invalid UTF-8 subjects when using the u modifier.

  11. Install Nette Utils via Composer

    master

    The recommended way to install Nette Utils is using Composer. This package provides a wide range of utility classes for arrays, filesystem operations, HTML generation, string manipulation, and more.

    Compatibility: Nette Utils 4.1 is compatible with PHP 8.2 through 8.5.

    composer require nette/utils
  12. Use Process piping and stdin correctly

    master

    When using Process for inter-process communication:

    • Piping: Passing one Process instance as the $stdin for another transfers ownership of the source's STDOUT pipe. The source process can no longer read its own output. Note: Piping is POSIX-only and will throw a NotSupportedException on Windows.
    • Writing to stdin: If you provide a string or resource as $stdin, it is written synchronously upfront. If the child process does not read this input while its own output buffer is filling, the process may block. To avoid this, pass null as $stdin and use writeStdInput() to feed the input incrementally.