Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.24% covered (success)
95.24%
20 / 21
93.33% covered (success)
93.33%
14 / 15
CRAP
0.00% covered (danger)
0.00%
0 / 1
Strings
95.24% covered (success)
95.24%
20 / 21
93.33% covered (success)
93.33%
14 / 15
18
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 init
83.33% covered (success)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
4.07
 instance
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 strlen
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 substr
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 strtolower
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 strtoupper
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 strstr
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 preg_match
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 preg_match_all
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 preg_split
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 preg_replace_callback
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 preg_replace
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 htmlspecialchars
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 htmlentities
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3/**
4 * The main string wrapper class.
5 *
6 * The class uses the mbstring extension if available. It's strongly recommended
7 * to use and extend this class instead of using direct string functions. Doing so,
8 * you guarantee your code is upwards compatible with UTF-8 improvements. All
9 * the string methods behavior is identical to that of the same named
10 * single byte string functions.
11 * This Source Code Form is subject to the terms of the Mozilla Public License,
12 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
13 * obtain one at https://mozilla.org/MPL/2.0/.
14 *
15 * @package   phpMyFAQ
16 * @author    Anatoliy Belsky <ab@php.net>
17 * @copyright 2009-2026 phpMyFAQ Team
18 * @license   https://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
19 * @link      https://www.phpmyfaq.de
20 * @since     2009-04-06
21 */
22
23declare(strict_types=1);
24
25namespace phpMyFAQ;
26
27use phpMyFAQ\Strings\Mbstring;
28use phpMyFAQ\Strings\StringBasic;
29
30/**
31 * Class Strings
32 *
33 * @package phpMyFAQ
34 */
35class Strings
36{
37    /**
38     * Instance.
39     */
40    private static Mbstring|StringBasic|null $instance = null;
41
42    /**
43     * Constructor.
44     */
45    final private function __construct()
46    {
47    }
48
49    /**
50     * Init.
51     *
52     * @param string $language Language
53     */
54    public static function init(string $language = 'en'): void
55    {
56        if (self::$instance !== null) {
57            return;
58        }
59
60        if (extension_loaded('mbstring') && function_exists('mb_strlen')) {
61            self::$instance = Mbstring::getInstance($language);
62            return;
63        }
64
65        self::$instance = StringBasic::getStringBasic($language);
66    }
67
68    /**
69     * Returns the initialized implementation, bootstrapping with the default
70     * language when init() has not been called yet.
71     */
72    private static function instance(): Mbstring|StringBasic
73    {
74        self::init();
75
76        return self::$instance ?? throw new \LogicException('Strings could not be initialized.');
77    }
78
79    /**
80     * Get string character count.
81     *
82     * @param string $str String
83     */
84    public static function strlen(string $str): int
85    {
86        return self::instance()->strlen($str);
87    }
88
89    /**
90     * Get a part of string.
91     *
92     * @param string $string String
93     * @param int $start Start
94     * @param int|null $length Length
95     */
96    public static function substr(string $string, int $start, ?int $length = 0): string
97    {
98        return self::instance()->substr($string, $start, $length);
99    }
100
101    /**
102     * Make a string lower case.
103     *
104     * @param string $str String
105     */
106    public static function strtolower(string $str): string
107    {
108        return self::instance()->strtolower($str);
109    }
110
111    /**
112     * Make a string upper case.
113     *
114     * @param string $str String
115     */
116    public static function strtoupper(string $str): string
117    {
118        return self::instance()->strtoupper($str);
119    }
120
121    /**
122     * Get the occurrence of a string within another.
123     *
124     * @param string $haystack Haystack
125     * @param string $needle Needle
126     * @param bool   $part Part
127     */
128    public static function strstr(string $haystack, string $needle, bool $part = false): string|false
129    {
130        return self::instance()->strstr($haystack, $needle, $part);
131    }
132
133    /**
134     * Match a regexp.
135     *
136     * @param array<array-key, mixed>|null $matches
137     */
138    public static function preg_match(
139        string $pattern,
140        string $subject,
141        &$matches = null,
142        int $flags = 0,
143        int $offset = 0,
144    ): int { // phpcs:ignore
145        return (int) self::instance()->preg_match($pattern, $subject, $matches, $flags, $offset);
146    }
147
148    /**
149     * Match a regexp globally.
150     *
151     * @param array<array-key, mixed>|null $matches
152     */
153    public static function preg_match_all(
154        string $pattern,
155        string $subject,
156        &$matches = null,
157        int $flags = 0,
158        int $offset = 0,
159    ): int { // phpcs:ignore
160        return (int) self::instance()->preg_match_all($pattern, $subject, $matches, $flags, $offset);
161    }
162
163    /**
164     * Split string by a regexp.
165     */
166    public static function preg_split(string $pattern, string $subject, int $limit = -1, int $flags = 0): array|bool
167    { // phpcs:ignore
168        return self::instance()->preg_split($pattern, $subject, $limit, $flags);
169    }
170
171    /**
172     * Search and replace by a regexp using a callback.
173     *
174     * @param callable(array<array-key, string>): string $callback
175     * @param string|string[] $subject
176     */
177    public static function preg_replace_callback(
178        string $pattern,
179        callable $callback,
180        string|array $subject,
181        int $limit = -1,
182        int &$count = 0,
183    ): string|array|null {
184        return self::instance()->preg_replace_callback($pattern, $callback, $subject, $limit, $count);
185    }
186
187    /**
188     * Search and replace by a regexp.
189     *
190     * @param string|string[] $pattern
191     * @param string|string[] $replacement
192     * @param string|string[] $subject
193     * @return string|string[]|null
194     */
195    public static function preg_replace(
196        string|array $pattern,
197        string|array $replacement,
198        string|array $subject,
199        int $limit = -1,
200        int &$count = 0,
201    ): string|array|null {
202        return self::instance()->preg_replace($pattern, $replacement, $subject, $limit, $count);
203    }
204
205    /**
206     * Convert special chars to HTML entities.
207     *
208     * @param string|null $string The input string.
209     * @param int         $quoteStyle Quote style
210     * @param string      $charset Character set, UTF-8 by default
211     * @param bool        $doubleEncode If set to false, no encoding of existing entities
212     */
213    public static function htmlspecialchars(
214        ?string $string = '',
215        int $quoteStyle = ENT_HTML5,
216        string $charset = 'utf-8',
217        bool $doubleEncode = false,
218    ): string {
219        return htmlspecialchars((string) $string, $quoteStyle, $charset, $doubleEncode);
220    }
221
222    /**
223     * Convert all applicable characters to HTML entities.
224     *
225     * @param string $string The input string.
226     * @param int    $quoteStyle Quote style
227     * @param string $charset Character set, UTF-8 by default
228     * @param bool   $doubleEncode If set to false, no encoding of existing entities
229     */
230    public static function htmlentities(
231        string $string,
232        int $quoteStyle = ENT_HTML5,
233        string $charset = 'utf-8',
234        bool $doubleEncode = false,
235    ): string {
236        return htmlentities($string, $quoteStyle, $charset, $doubleEncode);
237    }
238}