vielhuber / stringhelper
Collection of useful shorthand string related functions in PHP.
Installs: 4 079
Dependents: 3
Suggesters: 0
Security: 0
Stars: 8
Watchers: 2
Forks: 3
Open Issues: 0
Requires
- php: >=7.1
Requires (Dev)
- phpunit/phpunit: >=6.5
- vlucas/phpdotenv: >=4.1
- dev-master
- 6.5.0
- 6.4.9
- 6.4.8
- 6.4.7
- 6.4.6
- 6.4.5
- 6.4.4
- 6.4.3
- 6.4.2
- 6.4.1
- 6.4.0
- 6.3.9
- 6.3.8
- 6.3.7
- 6.3.6
- 6.3.5
- 6.3.4
- 6.3.3
- 6.3.2
- 6.3.1
- 6.3.0
- 6.2.9
- 6.2.8
- 6.2.7
- 6.2.6
- 6.2.5
- 6.2.4
- 6.2.3
- 6.2.2
- 6.2.1
- 6.2.0
- 6.1.9
- 6.1.8
- 6.1.7
- 6.1.6
- 6.1.5
- 6.1.4
- 6.1.3
- 6.1.2
- 6.1.1
- 6.1.0
- 6.0.9
- 6.0.8
- 6.0.7
- 6.0.6
- 6.0.5
- 6.0.4
- 6.0.3
- 6.0.2
- 6.0.1
- 6.0.0
- 5.9.9
- 5.9.8
- 5.9.7
- 5.9.6
- 5.9.5
- 5.9.4
- 5.9.3
- 5.9.2
- 5.9.1
- 5.9.0
- 5.8.9
- 5.8.8
- 5.8.7
- 5.8.6
- 5.8.5
- 5.8.4
- 5.8.3
- 5.8.2
- 5.8.1
- 5.8.0
- 5.7.9
- 5.7.8
- 5.7.7
- 5.7.6
- 5.7.5
- 5.7.4
- 5.7.3
- 5.7.2
- 5.7.1
- 5.7.0
- 5.6.9
- 5.6.8
- 5.6.7
- 5.6.6
- 5.6.5
- 5.6.4
- 5.6.3
- 5.6.2
- 5.6.1
- 5.6.0
- 5.5.9
- 5.5.8
- 5.5.7
- 5.5.6
- 5.5.5
- 5.5.4
- 5.5.3
- 5.5.2
- 5.5.1
- 5.5.0
- 5.4.9
- 5.4.8
- 5.4.7
- 5.4.6
- 5.4.5
- 5.4.4
- 5.4.3
- 5.4.2
- 5.4.1
- 5.4.0
- 5.3.9
- 5.3.8
- 5.3.7
- 5.3.6
- 5.3.5
- 5.3.4
- 5.3.3
- 5.3.2
- 5.3.1
- 5.3.0
- 5.2.9
- 5.2.8
- 5.2.7
- 5.2.6
- 5.2.5
- 5.2.4
- 5.2.3
- 5.2.2
- 5.2.1
- 5.2.0
- 5.1.9
- 5.1.8
- 5.1.7
- 5.1.6
- 5.1.5
- 5.1.4
- 5.1.3
- 5.1.2
- 5.1.1
- 5.1.0
- 5.0.9
- 5.0.8
- 5.0.7
- 5.0.6
- 5.0.5
- 5.0.4
- 5.0.3
- 5.0.2
- 5.0.1
- 5.0.0
- 4.9.9
- 4.9.8
- 4.9.7
- 4.9.6
- 4.9.5
- 4.9.4
- 4.9.3
- 4.9.2
- 4.9.1
- 4.9.0
- 4.8.9
- 4.8.8
- 4.8.7
- 4.8.6
- 4.8.5
- 4.8.4
- 4.8.3
- 4.8.2
- 4.8.1
- 4.8.0
- 4.7.9
- 4.7.8
- 4.7.7
- 4.7.6
- 4.7.5
- 4.7.4
- 4.7.3
- 4.7.2
- 4.7.1
- 4.7.0
- 4.6.9
- 4.6.8
- 4.6.7
- 4.6.6
- 4.6.5
- 4.6.4
- 4.6.3
- 4.6.2
- 4.6.1
- 4.6.0
- 4.5.9
- 4.5.8
- 4.5.7
- 4.5.6
- 4.5.5
- 4.5.4
- 4.5.3
- 4.5.2
- 4.5.1
- 4.5.0
- 4.4.9
- 4.4.8
- 4.4.7
- 4.4.6
- 4.4.5
- 4.4.4
- 4.4.3
- 4.4.2
- 4.4.1
- 4.4.0
- 4.3.9
- 4.3.8
- 4.3.7
- 4.3.6
- 4.3.5
- 4.3.4
- 4.3.3
- 4.3.2
- 4.3.1
- 4.3.0
- 4.2.9
- 4.2.8
- 4.2.7
- 4.2.6
- 4.2.5
- 4.2.4
- 4.2.3
- 4.2.2
- 4.2.1
- 4.2.0
- 4.1.9
- 4.1.8
- 4.1.7
- 4.1.6
- 4.1.5
- 4.1.4
- 4.1.3
- 4.1.2
- 4.1.1
- 4.1.0
- 4.0.9
- 4.0.8
- 4.0.7
- 4.0.6
- 4.0.5
- 4.0.4
- 4.0.3
- 4.0.2
- 4.0.1
- 4.0.0
- 3.9.9
- 3.9.8
- 3.9.7
- 3.9.6
- 3.9.5
- 3.9.4
- 3.9.3
- 3.9.2
- 3.9.1
- 3.9.0
- 3.8.9
- 3.8.8
- 3.8.7
- 3.8.6
- 3.8.5
- 3.8.4
- 3.8.3
- 3.8.2
- 3.8.1
- 3.8.0
- 3.7.9
- 3.7.8
- 3.7.7
- 3.7.6
- 3.7.5
- 3.7.4
- 3.7.3
- 3.7.2
- 3.7.1
- 3.7.0
- 3.6.9
- 3.6.8
- 3.6.7
- 3.6.6
- 3.6.5
- 3.6.4
- 3.6.3
- 3.6.2
- 3.6.1
- 3.6.0
- 3.5.9
- 3.5.8
- 3.5.7
- 3.5.6
- 3.5.5
- 3.5.4
- 3.5.3
- 3.5.2
- 3.5.1
- 3.5.0
- 3.4.9
- 3.4.8
- 3.4.7
- 3.4.6
- 3.4.5
- 3.4.4
- 3.4.3
- 3.4.2
- 3.4.1
- 3.4.0
- 3.3.9
- 3.3.8
- 3.3.7
- 3.3.6
- 3.3.5
- 3.3.4
- 3.3.3
- 3.3.2
- 3.3.1
- 3.3.0
- 3.2.9
- 3.2.8
- 3.2.7
- 3.2.6
- 3.2.5
- 3.2.4
- 3.2.3
- 3.2.2
- 3.2.1
- 3.2.0
- 3.1.9
- 3.1.8
- 3.1.7
- 3.1.6
- 3.1.5
- 3.1.4
- 3.1.3
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.9
- 3.0.8
- 3.0.7
- 3.0.6
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 2.9.9
- 2.9.8
- 2.9.7
- 2.9.6
- 2.9.5
- 2.9.4
- 2.9.3
- 2.9.2
- 2.9.1
- 2.9.0
- 2.8.9
- 2.8.8
- 2.8.7
- 2.8.6
- 2.8.5
- 2.8.4
- 2.8.3
- 2.8.2
- 2.8.1
- 2.8.0
- 2.7.9
- 2.7.8
- 2.7.7
- 2.7.6
- 2.7.5
- 2.7.4
- 2.7.3
- 2.7.2
- 2.7.1
- 2.7.0
- 2.6.9
- 2.6.8
- 2.6.7
- 2.6.6
- 2.6.5
- 2.6.4
- 2.6.3
- 2.6.2
- 2.6.1
- 2.6.0
- 2.5.9
- 2.5.8
- 2.5.7
- 2.5.6
- 2.5.5
- 2.5.4
- 2.5.3
- 2.5.2
- 2.5.1
- 2.5.0
- 2.4.9
- 2.4.8
- 2.4.7
- 2.4.6
- 2.4.5
- 2.4.4
- 2.4.3
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.9
- 2.3.8
- 2.3.7
- 2.3.6
- 2.3.5
- 2.3.4
- 2.3.3
- 2.3.2
- 2.3.1
- 2.3.0
- 2.2.9
- 2.2.8
- 2.2.7
- 2.2.6
- 2.2.5
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.9
- 2.1.8
- 2.1.7
- 2.1.6
- 2.1.5
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.9
- 2.0.8
- 2.0.7
- 2.0.6
- 2.0.5
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 1.9.9
- 1.9.8
- 1.9.7
- 1.9.6
- 1.9.5
- 1.9.4
- 1.9.3
- 1.9.2
- 1.9.1
- 1.9.0
- 1.8.9
- 1.8.8
- 1.8.7
- 1.8.6
- 1.8.5
- 1.8.4
- 1.8.3
- 1.8.2
- 1.8.1
- 1.8.0
- 1.7.9
- 1.7.8
- 1.7.7
- 1.7.6
- 1.7.5
- 1.7.4
- 1.7.3
- 1.7.2
- 1.7.1
- 1.7.0
- 1.6.9
- 1.6.8
- 1.6.7
- 1.6.6
- 1.6.5
- 1.6.4
- 1.6.3
- 1.6.2
- 1.6.1
- 1.6.0
- 1.5.9
- 1.5.8
- 1.5.7
- 1.5.6
- 1.5.5
- 1.5.4
- 1.5.3
- 1.5.2
- 1.5.1
- 1.5.0
- 1.4.9
- 1.4.8
- 1.4.7
- 1.4.6
- 1.4.5
- 1.4.4
- 1.4.3
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.9
- 1.3.8
- 1.3.7
- 1.3.6
- 1.3.5
- 1.3.4
- 1.3.3
- 1.3.2
- 1.3.1
- 1.3.0
- 1.2.9
- 1.2.8
- 1.2.7
- 1.2.6
- 1.2.5
- 1.2.4
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.9
- 1.1.8
- 1.1.7
- 1.1.6
- 1.1.5
- 1.1.4
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
This package is auto-updated.
Last update: 2025-04-09 11:57:47 UTC
README
⛏️ stringhelper ⛏️
motivation
this package is a collection of various helpers for string manipulation, validation, and utility functions designed to simplify the life of php developers. it streamlines tasks like checking variable existence, comparing values, and handling dates, urls, and emails. this tool enhances efficiency by offering concise, reusable methods for everyday coding challenges.
installation
composer require vielhuber/stringhelper
usage
existence
// check existence if (__x($var)) { } if (__x(@$var)) { } // check non-existence if (__nx($var)) { } if (__nx(@$var)) { } // check existence (without stfu-operator) if (__rx($var)) { } if (__fx(fn() => $var)) { } // check non-existence (without stfu-operator) if (__rnx($var)) { } if (__fnx(fn() => $var)) { }
equality
// php has a lot of pitfalls, when comparing loosely if( 0 == 'true' ) // true if( 0 == 'str' ) // true if( 'null' == null ) // false if( '0' == null ) // false if( '0' == true ) // false if( '0' == false ) // true if( 'false' == true ) // true if( 'false' == false ) // false if( new stdClass == true ) // true if( [] == false ) // true if( [] == null ) // true if( [''] == [] ) // false if( [''] == [0] ) // true if( 0 == '' ) // true if( 0 == ' ' ) // true if( -1 == true ) // true if( '-1' == true ) // true // this non-strict equality is symmetric, but not transitive $a = ''; $b = 0; $c = 'oh'; $a == $b; // true $b == $c; // true $c == $a; // false // to overcome this issue, we... // ...use strict comparison when possible if( $var === 'foo' ) { } // ...use loose comparison when appropriate if( $_GET['number'] == 1337 ) { } // ...check for truthness / falsiness with these helper methods if( __true($var) ) { } if( __false($var) ) { } // be aware, that __true is not always the logic negation of __false __true(null) // false __false(null) // false
value
// get variable if exists, otherwise null __v( $var ) // get variable if exists, otherwise 'default' __v( $var, 'default' ) // get first variable that exists, otherwise null __v( $var1, $var2, $var3 ) // get variable if exists, otherwise the empty object __e( $var ) __e( $var, 'default' ) __e( $var1, $var2, $var3 )
loop
// loop only if exists foreach (__e($array) as $array__key => $array__value) { }
try
// if you are unsure, if a variable is even set before checking its existence, // simply prefix it with the stfu-operator @ if( __x(@$var) ) if( __nx(@$var) ) if( __true(@$var) ) if( __false(@$var) ) if( @$var === 'foo' ) if( @$_GET['number'] == 1337 ) echo __v(@$var) foreach( __e(@$array) as $array__key=>$array__value)
A short note on the usage of @: In this concept we use @-operator that hides errors. We are aware of its potential misuse and also of its benefits.
Be careful when using @$a['undefined'], there can be 2 possible errors: a missing variable or a missing index. In both cases, we intentionally prevent the parser from stopping and catch the resulting null value. Be aware: If $a is a string, @$a['undefined'] evaluates to $a[0] since php coerces 'undefined' to 0 and therefore exists.
Another general rule of thumb: Don't use the operator before function calls (@__x($a['undefined']).
A caveat is that the @-operator does not catch any fatal runtime errors since PHP 8 anymore.
For that there is also another more sophisticated way of checking the existence of variables:
If $var
is totally undefined, the following expressions evaluate correctly to false:
__fx(fn()=>$var) __fx(fn()=>$var['foo']['bar']['baz']) __fx(fn()=>$var())
Be aware that arrow functions are only available from php 7.4; Prior versions should use:
__fx(function () use (&$var) { return $var['foo']['bar']['baz']; });
Another approach is to pass (potentially undefined) variables by reference to the rx
/nrx
-helpers:
__rx($var) // false __rx($var['foo']['bar']['baz']) // false __nrx($var) // true
Be aware that undefined variables are defined as null by php after the check:
array_key_exists('foo', get_defined_vars()); // false __rx($foo); array_key_exists('foo', get_defined_vars()); // true
classes
// consider the following laravelish code class Person { public $id; function __construct($id) { $this->id = $id; } static function find($id) { // mock example (normally lookup in database) if( $id === 1 || $id === 2 ) { return new Person($id); } else { return null; } } function getAddress() { if( $this->id === 1 ) { return new Address(); } else { return null; } } } class Address { function getCountry() { return new Country(); } } class Country { function getName() { return 'Germany'; } } echo Person::find(1)->getAddress()->getCountry()->getName(); // 'Germany' echo Person::find(2)->getAddress()->getCountry()->getName(); // fails because person with id 2 has no address echo Person::find(3)->getAddress()->getCountry()->getName(); // fails because person with id 3 does not even exist // due to the fact that the null propagating method call operator // (https://wiki.php.net/rfc/nullsafe_calls) is still a rfc, we cannot write echo Person::find(3)?->getAddress()?->getCountry()?->getName(); // null // we therefore return a null model object class Person { public $id; function __construct($id) { $this->id = $id; } static function find($id) { if( $id === 1 || $id === 2 ) { return new Person($id); } else { return __empty(); } } function getAddress() { if( $this->id === 1 ) { return new Address(); } else { return __empty(); } } } class Address { function getCountry() { return new Country(); } } class Country { function getName() { return 'Germany'; } } // this empty helper object is quite useful for returning an empty class which is callable with undefined functions __empty() // we can no conveniently call those chains... echo Person::find(1)->getAddress()->getCountry()->getName(); // 'Germany' echo Person::find(2)->getAddress()->getCountry()->getName(); // '' echo Person::find(3)->getAddress()->getCountry()->getName(); // '' // ...check for existence... if( __x(Person::find(1)->getAddress()->getCountry()->getName()) ) { } // ...check for strict equality... if( Person::find(1)->getAddress()->getCountry()->getName() === 'Germany' ) { } // ...get a value... echo __v( Person::find(1)->getAddress()->getCountry()->getName(), 'default' ); // ...and loop when possible foreach( Person::find(1)->getAddress()->getCountry() as $value ) { }
helpers
there are also some other neat little helpers available.
// check if all variables exist if( __x_all('foo', 'bar', null) ) // false if( __x_all(['foo', 'bar', null]) ) // false if( __x_all('foo', 'bar', 'baz') ) // true if( __x_all(['foo', 'bar', 'baz']) ) // true if( __nx_all('foo', 'bar', null) ) // true if( __nx_all('foo', 'bar', 'baz') ) // false // check if one variable exists if( __x_one('foo', 'bar') ) // true if( __x_one('', null) ) // false if( __x_one(['foo', 'bar']) ) // true if( __x_one(['', null]) ) // false if( __nx_one('foo', 'bar') ) // false if( __nx_one('', null) ) // true // check truthness of all variables if( __true_all(true, true, true) ) // true if( __true_all([true, true, null]) ) // false if( __true_all(true, '1') ) // true if( __true_all([true, false]) ) // false if( __false_all('foo', 'bar', null) ) // false if( __false_all(false) ) // true // check truthness of one variable if( __true_one(true, true, true) ) // true if( __true_one([true, true, null]) ) // true if( __true_one(true, '1') ) // true if( __true_one([true, false]) ) // true if( __false_one('foo', 'bar', null) ) // false if( __false_one(false) ) // true // cookies __cookie_set('cookie_name', 'cookie_value') // set cookie for 30 days __cookie_set('cookie_name', 'cookie_value', 7) // set cookie for 7 days __cookie_set('cookie_name2', ['can also', 'store', 'arrays'], 7) __cookie_set('cookie_name3', 'cookie_value', 7, [ 'path' => '/', 'domain' => '', 'samesite' => 'None', 'secure' => true, 'httponly' => false ]) // more options like SameSite (also works with PHP<7.3) __cookie_exists('cookie_name') // true __cookie_get('cookie_name') // 'cookie_value' __cookie_get('cookie_name2') // ['can also', 'store', 'arrays'] __cookie_delete('cookie_name') // anonymize ipv4/ipv6 addresses __anonymize_ip('207.142.131.005') // 207.142.131.XXX __anonymize_ip('001:0db8:0000:08d3:0000:8a2e:0070:7344') // 2001:0db8:0000:08d3:0000:8a2e:XXXX:XXXX __anonymize_ip() // anonymizes ip from $_SERVER['REMOTE_ADDR'] // show password strength (1-3) __password_strength('3iu') // 1 __password_strength('3iurehkHEDJ') // 2 __password_strength('3iurehkHEDJK§$R$A') // 3 // generate password __password_generate( length: 20, chars: ['a-z', 'A-Z', '0-9', '$!?'], // password contains at minimum one character of each value exclude: 'lI' // exclude confusing chars ) // calculate distance in meters between two lat/lng points with the haversine formula __distance_haversine([48.576809, 13.403207], [48.127719, 11.575344]) // 143999 // validate iban __validate_iban('DE07123412341234123412') // true __validate_iban('DE07123412341234123442') // false // checks if string is a valid url (also works with umlauts and without external lib like idna) __validate_url('https://vielhuber.de') // true // check if string is a valid email (also works with umlauts and without external lib like idna) __validate_email('david@vielhuber.de') // true // checks if a date is valid (string in english/german, timestamp or date format) __validate_date('2000-01-01') // true __validate_date('01.01.2000') // true __validate_date('29.02.2001') // false __validate_date(new DateTime('2000-01-01')) // true __validate_date(946713600) // true // checks if a string is a valid date format __validate_date_format('d.m.Y') // true __validate_date_format('Y-m-d') // true __validate_date_format('01.m.Y') // true __validate_date_format('foo') // false // checks if a string is a valid date modifier __validate_date_mod('+6 months') // true __validate_date_mod('foo') // false // simple date helper __date('2000-01-01') // 2000-01-01 __date('2000-01-01', 'd.m.Y') // 01.01.2000 __date('2001-02-29', 'd.m.Y') // null; returns null if date is invalid, otherwise formatted date __date('2000-01-01', '+6 months') // 2000-07-01; allows date modifications __date('2000-01-01', 'd.m.Y', '+6 months') // 01.07.2000 __date('01.01.2000') // 2000-01-01; also accepts other formats __date('01.01.20') // 2020-01-01; correctly interprets some german variants __date('01.01.39') // 2039-01-01; exceeds 32-bit ranges __date('now') // 2019-05-28; also accepts strings __date('2019-12-02 12:00:00', 'd.m.Y H:i:s') // 02.12.2019 12:00:00 __date('2019-12-02T12:00:00', 'd.m.Y H:i:s') // 02.12.2019 12:00:00 __date() // 2019-05-28 __date('') // null __date(null) // null __date('d.m.Y',null) // null $unknown = null; __date($unknown) // null __date(strtotime('2000-01-01'), 'd.m.Y') // 01.01.2000; also accepts timestamps __date(strtotime('2000-01-01'), 'd.m.Y', '+6 months') // 01.07.2000 __date(new DateTime('2000-01-01'), 'd.m.Y') // 01.01.2000; also accepts datetime objects __date('d.m.Y') // 01.01.2000; you can even switch arguments (they are sorted magically) __date('d.m.Y', 'now') // 2019-05-28 __date('+6 months') // 2019-11-28 // outputs a valid formatted value for input datetime-local __datetime('01.01.2000') // 2000-01-01T00:00 __datetime('01.01.2000 18:00') // 2000-01-01T18:00 // set time of date as string to begin of day __date_reset_time('2000-01-01 16:30:00') // 2000-01-01 00:00:00 __date_reset_time('2000-01-01') // 2000-01-01 00:00:00 __date_reset_time('01.01.2000') // 2000-01-01 00:00:00 // get age from date __age_from_date('2000-01-01') // 20 __age_from_date('2000-01-01', '2010-01-01') // 10 __age_from_date_weeks('2000-01-01') // 1083 __age_from_date_weeks('2000-01-01', '2010-01-01') // 521 __age_from_date_days('2000-01-01') // 7587 __age_from_date_days('2000-01-01', '2010-01-01') // 3653 // strftime >=php 8.1 setlocale(LC_TIME, 'de_DE.utf8'); __strftime('%A, %d. %B %Y', strtotime('2001-01-01')); // Montag, 01. Januar 2001 // remove useless zero digits from decimals __remove_zero_decimals(1337) // 1337 __remove_zero_decimals('1337') // 1337 __remove_zero_decimals('1337.40') // 1337.4 __remove_zero_decimals('1337,40') // 1337.4 __remove_zero_decimals(1337.0) // 1337 __remove_zero_decimals(1337.4) // 1337.4 __remove_zero_decimals(1337.42) // 1337.42 __remove_zero_decimals(1337.424) // 1337.424 // remove leading zeros __remove_leading_zeros('01337') // 1337 // normalizes phone numbers (din, germany) __phone_normalize('(0)89-12 456 666') // +49 89 12456666 __phone_tokenize('(0)89-12 456 666') // ['country_code' => '49', 'area_code' => '89', 'number' => '12456666'] __phone_country_codes() // ['49', ...] __phone_area_codes() // ['89', '151', ...] __phone_area_codes_landline() // ['89', ...] __phone_area_codes_mobile() // ['151', ...] __phone_is_landline('(0)89-12 456 666') // true __phone_is_mobile('(0)89-12 456 666') // false // parse cumulated mail string (RFC5322) __email_tokenize_str2arr('Max Mustermann <mail1@tld.com>; mail2@tld.com') // [['email' => 'mail1@tld.com', 'name' => 'Max Mustermann'],['email' => 'mail2@tld.com', 'name' => null]]; __email_tokenize_arr2str([['email' => 'mail1@tld.com', 'name' => 'Max Mustermann'],['email' => 'mail2@tld.com', 'name' => null]]); // 'Max Mustermann <mail1@tld.com>; mail2@tld.com' // normalize url __url_normalize('www.tld.com') // https://www.tld.com __url_normalize('http://tld.com/') // http://tld.com // minify html __minify_html('<!DOCTYPE html> <title>shortest valid html5 document</title> <p>yay</p>') // <!DOCTYPE html><title>shortest valid html5 document</title><p>yay</p> // proper string to domdocument and domdocument to string conversion (respects original structure and fixes lots of caveats) __dom_to_str(__str_to_dom('<ul><li></li><li></li></ul>')) // <ul><li></li><li></li></ul> __dom_to_str(__str_to_dom('<custom-component @click.prevent="foo()"></custom-component>')) // <custom-component @click.prevent="foo()"></custom-component> // translate strings __translate_google('Sein oder Nichtsein; das ist hier die Frage.', 'de', 'en', '**API Key**') // To be or not to be; that is the question. __translate_microsoft('Sein oder Nichtsein; das ist hier die Frage.', 'de', 'en', '**API Key**') // Being or not being; that is the question here. __translate_deepl('Sein oder Nichtsein; das ist hier die Frage.', 'de', 'en', '**API Key**') // To be or not to be; that is the question here. // work conveniently with all major ai apis $ai = __ai( service: 'chatgpt', // chatgpt|claude|gemini model: 'gpt-4o', // gpt-4o|claude-3-5-sonnet-20240620|gemini-1.5-flash|... temperature: 0.7, // controls the randomness of the text generated api_key: '**API Key**' ); $ai->ask('Wer wurde 2018 Fußball-Weltmeister?'); // ['response' => 'Frankreich.', 'success' => true] $ai->ask('Was ist auf dem Bild zu sehen?', 'lorem.jpg'); // ['response' => 'Auf dem Bild ist eine Katze zu sehen.', 'success' => true] $ai->ask('Wie lautet das erste Wort in der PDF?', 'lorem.pdf'); // ['response' => 'Das erste Wort lautet "Lorem".', 'success' => true] $ai->ask('Fasse die folgenden Dokumente zusammen.', ['1.pdf','2.jpg']); // ['response' => '...', 'success' => true] $ai = __ai( session_id: $ai->session_id // submit session to continue a conversation afterwards ($ai->session_id) ); $ai->ask('Was habe ich vorher gefragt?'); // ['response' => 'Du hast gefragt: "Wie lautet das erste Wort in der PDF?"', 'success' => true] $ai->cleanup(); // (remotely) deletes the data of the current session $ai->cleanup_all(); // (remotely) deletes all data $ai->enable_log('output.log'); $ai->disable_log(); // remove emojis from string __remove_emoji('Lorem 🤷 ipsum ❤ dolor 🥺 med') // Lorem ipsum dolor med // remove accents from string __remove_accents('Ǻºĺ') // Cool __remove_accents('Äťśçĥ') // Ätsch __remove_accents('Äťśçĥ', true) // Aetsch // remove non printable chars from string __remove_non_printable_chars('foo�bar') // foobar // string to slug (sanitize string) __slug('This string will be sanitized!') // this-string-will-be-sanitized // generate a random string __random_string() // edPhi34d __random_string(10) // abCa321aC6 __random_string(16, 'idkfa') // idifafafifaifafk // shuffle array (no reference) __shuffle(['foo','bar','baz']); // ['bar','baz','foo'] // shuffle associative array and preserve keys __shuffle_assoc(['foo' => 'bar', 'bar' => 'baz', 'baz' => 'foo']) // ['bar' => 'baz', 'baz' => 'foo', 'foo' => 'bar'] // sort with umlauts (DIN-5007-2) $arr = ['äther', 'Äther2', 'Ü12.pdf', 'Ü2.pdf']; usort($arr, function($a, $b) { return __mb_strcmp($a, $b); }); // ['Äther2', 'Ü12.pdf', 'Ü2.pdf', 'äther'] usort($arr, function($a, $b) { return __mb_strcasecmp($a, $b); }); // ['äther', 'Äther2', 'Ü12.pdf', 'Ü2.pdf'] usort($arr, function($a, $b) { return __mb_strnatcmp($a, $b); }); // ['Äther2', 'Ü2.pdf', 'Ü12.pdf', 'äther'] usort($arr, function($a, $b) { return __mb_strnatcasecmp($a, $b); }); // ['äther', 'Äther2', 'Ü2.pdf', 'Ü12.pdf'] // array order sort by many $arr = [['a' => 17, 'b' => 42], ['a' => 13, 'b' => 19]] usort($arr, __array_multisort([ ['a', 'asc'], ['b', 'asc'] ])) // [['a' => 13, 'b' => 19], ['a' => 17, 'b' => 42]] usort($arr, __array_multisort(function($v) { return [ [$v['a'], 'asc'], [$v['b'], 'asc'] ]; })) // [['a' => 13, 'b' => 19], ['a' => 17, 'b' => 42]] collect($arr)->sort( __array_multisort([ ['a', 'asc'], ['b', 'asc'] ]) ) // can also be used by laravel collections // considers umlauts (DIN-5007-2) $arr = [['foo' => 'zoo'], ['foo' => 'Äther']] usort($arr, __array_multisort([['foo', 'asc']])) // [['foo' => 'Äther'], ['foo' => 'zoo']] // array group by $a = ['a' => 17, 'b' => 42, 'c' => 'foo'] $b = ['a' => 19, 'b' => 20, 'c' => 'bar'] $c = ['a' => 17, 'b' => 42, 'c' => 'baz'] $arr = [$a, $b, $c] __array_group_by($arr, 'a') // [17 => [$a, $c], 19 => [$b]] __array_group_by($arr, 'a', 'b') // [17 => [42 => [$a, $c]], 19 => [20 => [$b]]] __array_group_by($arr, function($v) { return $v['a']; }) // [17 => [$a, $c], 19 => [$b]] __array_group_by($arr, function($v) { return $v['a']; }, function($v) { return $v['b']; }) // [17 => [42 => [$a, $c]], 19 => [20 => [$b]]] $arr = collect([collect($a), collect($b), collect($c)]) __array_group_by($arr, function($v) { return $v->get('a'); }) // can also be used by laravel collections // array group by aggregate $a = ['a' => 17, 'b' => 42, 'c' => 'foo'] $b = ['a' => 19, 'b' => 20, 'c' => 'bar'] $c = ['a' => 17, 'b' => 42, 'c' => 'baz'] $arr = [$a, $b, $c] __array_group_by_aggregate($arr, 'a', [ 'b' => function($a, $b) { return $a+$b; }, 'c' => function($a, $b) { return $a.', '.$b; }, ]) // [['a' => 17, 'b' => 84, 'c' => 'foo, baz'], ['a' => 19, 'b' => 20, 'c' => 'bar']] __array_group_by_aggregate($arr, ['a','b'], [ 'c' => function($a, $b) { return $a.', '.$b; }, ]) // [['a' => 17, 'b' => 42, 'c' => 'foo, baz'], ['a' => 19, 'b' => 20, 'c' => 'bar']] // array unique (that works with multidimensional arrays) __array_unique([1,2,2]) // [1,2] __array_unique([['foo'=>'bar'],['bar'=>'baz'],['foo'=>'bar']]) // [['foo'=>'bar'],['bar'=>'baz']] // recursively change values of array of arrays (only leaf nodes) __array_map_deep(['foo','bar'=>['baz','gnarr']], function($a) { return $a.'!'; }) // ['foo!','bar'=>['baz!','gnarr!']] __array_map_deep([[[[[[[[[[[[[[[true]]]]]]]]]]]]]]], function($a) { return !$a; }) // [[[[[[[[[[[[[[[false]]]]]]]]]]]]]]] __array_map_deep( [[[[[[[[[[[[[[[42 => 'no', 7 => 'ok']]]]]]]]]]]]]]], function ($value, $key) { return $key === 42 ? $value : $value . '!'; } ) // [[[[[[[[[[[[[[[42 => 'no', 7 => 'ok!']]]]]]]]]]]]]]] __array_map_deep( ['foo'=>['bar'=>'baz'],'bar'=>['baz'=>'gnarr'],'gnarr'=>['foo'=>'gnaz']], function($value,$key,$key_chain) { return in_array('bar',$key_chain)?$value.'!':$value; } ) // ['foo'=>['bar'=>'baz!'],'bar'=>['baz'=>'gnarr!'],'gnarr'=>['foo'=>'gnaz']] $output = []; array_map_deep( [1=>[2=>[3=>[4=>[5=>'ok1'],6=>[7=>'ok2']]]],8=>'ok3'], function($value,$key,$key_chain) use(&$output) { $output[] = $value.': '.implode('.',$key_chain); } ) echo implode(' - ', $output) // ok1: 1.2.3.4.5, ok2: 1.2.3.6.7, ok3: 8 __array_map_deep(['foo','bar'=>(object)['baz','gnarr']], function($a) { return $a.'!'; }) // ['foo!','bar'=>(object)['baz!','gnarr!']] __array_map_deep(['foo','bar'=>json_encode(['baz','gnarr'])], function($a) { return $a.'!'; }) // ['foo!', 'bar'=>json_encode(['baz!', 'gnarr!'])] // recursively change values of array of arrays (with parent nodes; be careful when changing the array structure) __array_map_deep_all(['foo'=>'bar','bar'=>['baz'=>'gnarr','gnarr'=>'baz']], function($value, $key, $key_chain) { if (is_array($value) && array_key_exists('baz', $value) && $value['baz'] === 'gnarr') { $value['gnarr'] = 'baz2'; } return $value; }) // ['foo'=>'bar','bar'=>['baz'=>'gnarr','gnarr'=>'baz2']] // array walk recursive (with parent nodes; be careful when changing the array structure) $arr = ['foo' => 'bar', 'bar' => ['baz' => 'gnarr', 'gnarr' => 'baz']] __array_walk_recursive_all($arr, function (&$value, $key, $key_chain) { if (is_array($value) && array_key_exists('baz', $value) && $value['baz'] === 'gnarr') { $value['gnarr'] = 'baz2'; } }) $arr // ['foo'=>'bar','bar'=>['baz'=>'gnarr','gnarr'=>'baz2']] // array filter recursive __array_filter_recursive_all( ['foo' => ['foo' => ['foo' => ['foo' => ['foo' => []]]]]], function($value, $key, $key_chain) { return $key === 'foo' && empty($value); } ) // [] // array map for keys __array_map_keys(function($k) { return $k.'!'; }, ['foo' => 'bar', 'bar' => 'baz']) // ['foo!' => 'bar', 'bar!' => 'baz'] // array map for keys and values __array_map_keys_values(function($k,$v) { return [$k.'!', $v.'?']; }, ['foo' => 'bar', 'bar' => 'baz']) // ['foo!' => 'bar?', 'bar!' => 'baz?'] // ask question on cli $answer = __ask('What\'s your name?') // free input $answer = __ask('Choose your destiny: [1] red pill [2] blue pill', [1,2]) // only accept specific chars/integers // show progress on cli echo 'Searching for TOE (theory of everything)...'.PHP_EOL; $i = 0; while($i <= 100) { __progress($i, 100, 'Loading...', 75, '#'); usleep($i < 90 ? 10000 : 250000); $i++; } echo PHP_EOL.'Answer: 42'; /* Searching for TOE (theory of everything)... Loading... [############################################################################] 100% Answer: 42 */ // simple multibyte version of sprintf sprintf('%7.7s', 'mäh') // ' mäh' __mb_sprintf('%7.7s', 'mäh') // ' mäh' // encode arbitrary data to string $data = ['foo' => 'bar', 'bar' => 'baz']; $str = __encode_data($data) // 'YToyOntzOjM6ImZvbyI7czozOiJiYXIiO3M6MzoiYmFyIjtzOjM6ImJheiI7fQ==' __decode_data($str) // ['foo' => 'bar', 'bar' => 'baz'] // support for multiple arguments __decode_data(__encode_data(['foo', 'bar'])) // ['foo', 'bar']); __decode_data(__encode_data('foo', 'bar')) // ['foo', 'bar']); // this can be useful to enrich form fields with additional data echo '<input name="foo['.__encode_data($data).']" value="bar" />'; __decode_data(array_key_first($_POST['foo'])) // ['foo' => 'bar', 'bar' => 'baz'] // this can also be useful to create a poor mans index foreach($a as $a__value) { $index[__encode_data($a__value['foo'],$a__value['bar'])] = null; } foreach($b as $b__value) { if(array_key_exists(__encode_data($b__value['foo'],$b__value['bar']),$index)) { /* ... */ } } // generate uuid/guid v4 __uuid() // 19028aea-ccb6-4b32-9e5d-1243c3a77bb1 // validate uuid v4 __validate_uuid('19028aea-ccb6-4b32-9e5d-1243c3a77bb1') // true __validate_uuid('00000000-0000-0000-0000-000000000000') // false __validate_uuid('00000000-0000-0000-0000-000000000000', false) // true (weak check) // create lexicographically ordered string ids like in firebase __pushId() // -LMsSyccg4OavBCZxRAA // strip string __strip('Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam.', 12) // Lorem ipsum... // strip numeric (0-9.,) __strip_numeric('the answer is 42.00') // the answer is // strip non-numeric (all except 0-9.,) __strip_nonnumeric('the answer is 42.00') // 42.00 // strip digit (0-9) __strip_numeric('the answer is 42.00') // the answer is // strip non-digit (all except 0-9) __strip_nondigit('the answer is 42') // 42 // strip non-chars (all except a-z and umlauts) __strip_nonchars('the Änswer is 42.-+&!foo') // the Änswer is foo // strip whitespace __strip_whitespace('the answer is 42') // theansweris42 __strip_whitespace('the answeris42') // theansweris42 // strip whitespace (collapsed) __strip_whitespace_collapsed('the answer is 42') // the answer is 42 __strip_whitespace_collapsed('the answer is 42 ') // the answer is 42 // strip specific tags (optionally with content) of html string __strip_tags('<p>foo</p><iframe src="#"></iframe><script>alert();</script><p>bar</p>', 'script') // <p>foo</p><iframe src="#"></iframe>alert();<p>bar</p> __strip_tags('<p>foo</p><iframe src="#"></iframe><script>alert();</script><p>bar</p>', ['iframe','script'], true) // <p>foo</p><p>bar</p> // split string by new line __split_newline('foo bar baz') // ['foo','bar','baz'] // add space after every 4th character (first remove whitespace, do it bytesafe, don't add a trailing space like chunk_split) __split_whitespace('DE07123412341234123412', 4) // 'DE07 1234 1234 1234 1234 12' __split_whitespace(' föö bäär ', 3) // 'föö bää r' // remove empty lines __remove_emptylines('foo bar baz') // foo\nbar\nbaz // remove new lines __remove_newlines('foo bar<br/> baz') // foobarbaz __remove_newlines('foo bar<br/> baz', ' ') // foo bar baz // reverse of nl2br __br2nl('foo<br/>bar') // foo //bar // truncate/trim long strings __truncate_string('Lorem ipsum dolor sit amet, consectetuer.', 20); // Lorem ipsum dolor ... __truncate_string('Lorem ipsum dolor sit amet, consectetuer.', 20, '…'); // Lorem ipsum dolor … // trim whitespace (including , tabs and line breaks) __trim_whitespace(' string including nasty whitespace chars ') // 'string including nasty whitespace chars' // trim every item in array __atrim(['foo ','bar',' baz']) // ['foo','bar','baz'] // trim every line in multiline string __trim_every_line('foo bar baz ') // foo //bar //baz // trim like it should be: // - works recursively // - works with whole words __trim('<br><br/><p></p>foo bar baz<br/><br/><br><br/>', ['<br/>','<br>','<p></p>']) // foo bar baz __ltrim('<br><br/><p></p>foo bar baz<br/><br/><br><br/>', ['<br/>','<br>','<p></p>']) // foo bar baz<br/><br/><br><br/> __rtrim('<br><br/><p></p>foo bar baz<br/><br/><br><br/>', ['<br/>','<br>','<p></p>']) // <br><br/><p></p>foo bar baz // remove keys from associative array __arr_without(['foo' => 'bar', 'bar' => 'baz', 'baz' => 'foo'], ['bar', 'baz']) // ['foo' => 'bar'] // reverse string (grapheme safe, works also without intl extension) __strrev('hello❤️world') // dlrow❤️olleh // check if string is json __string_is_json('[]') // true __string_is_json('{"foo":"bar"}') // true __string_is_json('["foo" => "bar"]') // false __string_is_json([]) // false __string_is_json((object)[]) // false // check if string is html __string_is_html('foo') // false __string_is_html('<p>foo</p>') // true __string_is_html('foo bar') // false __string_is_html('foo bar') // true // check if string is serialized __is_serialized('a:1:{s:3:"foo";s:3:"bar";}') // true __is_serialized('idkfa') // false __is_serialized('b:0;') // true __is_serialized('a:1:{s:3:\"foo\";s:3:\"bar\";}') // false __is_serialized('a:1:{42}') // false // check if string is base64 encoded __is_base64_encoded('dGhpcyBpcyBjb29sIHN0dWZm') // true __is_base64_encoded('#ib3498r') // false __is_base64_encoded('al3Vna##2dqa#Gdm') // false __is_base64_encoded((object)[]) // false // check if variable is of laravel type 'Illuminate\Database\Eloquent\Builder' __is_eloquent_builder($var) // true|false // extract part from string __extract('<a href="#foo">bar</a>','href="','">') // #foo __extract('<a href="#foo">bar</a>','">','</a') // bar // find all occurences of substring in string __strposx('bar foo baz foobar', 'foo') // [4,12] // find nth occurence of substring in string __strposnth('bar foo baz foobar', 'foo', 2) // 12 // check if key is first/last key in foreach loop $array = ['foo','bar']; foreach($array as $array__key=>$array__value) { if( __fkey($array__key, $array) ) { } if( __lkey($array__key, $array) ) { } } $array = ['foo','bar']; foreach($array as $array__value) { // (warning: don't call get_loop_status($array) twice inside an interation, // since it modifies the internal pointer of the array) $loop_status = __loop_status($array); if($loop_status->is_first) {} if($loop_status->is_last) {} if($loop_status->is_not_first) {} if($loop_status->is_not_last) {} } // get last item of array __last(['foo', 'bar', 'baz']) // 'baz' // get first item of array __first(['foo', 'bar', 'baz']) // 'foo' __first(['foo' => 'bar', 'bar' => 'baz']) // 'bar' // get first key of array __first_key(['foo' => 'bar', 'bar' => 'baz']) // 'foo' // get random element from array __rand(['foo', 'bar', 'baz']) // 'bar' // remove first/last item of array (and reindex array) __remove_first(['foo', 'bar', 'baz']) // ['bar','baz'] __remove_last(['foo', 'bar', 'baz']) // ['foo','bar'] // uppercase helpers (mb safe) __first_char_is_uppercase('Foo') // true __first_char_is_uppercase('bar') // true __set_first_char_uppercase('baz') // Baz __set_first_char_uppercase('übel') // Übel // convert array to object __array_to_object(['foo']) // {0: 'foo'} __array_to_object(['foo','bar']) // {0: 'foo', 1: 'bar'} __array_to_object(['foo' => 'bar']) // {foo: 'bar'} __array_to_object(['foo','bar' => ['foo','bar']]) // {0: 'foo', bar: {0: 'foo', 1: 'bar'}} // convert object to array __object_to_array((object)['foo']) // ['foo'] __object_to_array((object)['foo','bar']) // ['foo','bar'] __object_to_array((object)['foo' => 'bar']) // ['foo' => 'bar'] __object_to_array((object)['foo','bar' => (object)['foo','bar']]) // ['foo', 'bar' => ['foo','bar']] // convert variable to array __array() // [] __array('foo') // ['foo'] __array(['foo']) // ['foo'] __array(['foo','bar']) // ['foo','bar'] __array((object)['foo','bar']) // ['foo','bar'] __array((object)['foo','bar' => (object)['foo','bar']]) // ['foo', 'bar' => ['foo','bar']] // convert variable to object __object() // {} __object('foo') // {0: 'foo'} __object(['foo']) // {0: 'foo'} __object(['foo','bar']) // {0: 'foo', 1: 'bar'} __object(['foo' => 'bar']) // {foo: 'bar'} __object((object)['foo','bar']) // {0: 'foo',1: 'bar'} __object(['foo','bar' => ['foo','bar']]) // {0: 'foo', bar: {0: 'foo', 1: 'bar'}} // check if item can be looped (is a non empty array, object or collection) __can_be_looped([1,2]) // true __can_be_looped((object)[1,2]) // true __can_be_looped([]) // false // generate nested foreach loop of n levels $a = [1, 2]; $b = [3, 4]; $c = [5, 6]; $output = []; $fn = function ($x, $y, $z) use (&$output) { $output[] = $x . '' . $y . '' . $z; }; __foreach_nested($a, $b, $c, $fn); print_r($output); // same as foreach($a as $a__value) { foreach($b as $b__value) { foreach($c as $c__value) { $fn($x, $y, $z); } } // ['135', '136', '145', '146', '235', '236', '245', '246'] // removes recursively all items from array or object or collection that are considered empty (indexes are not reindexed) $arr = [0 => ['foo',0,'0',null,''], null, 2 => [['',''],[null]]]; __remove_empty($arr) // [0 => ['foo',0,'0']] __remove_empty($arr, [0,'0']) // [0 => ['foo']] (provide additional values that are considered empty) __remove_empty($arr, null, function ($value) { return (is_array($value) && empty($value)) || (is_string($value) && $value === ''); }) // [0 => ['foo',0,'0',null], null, 2 => [1 => [null]]] (provide a callback function) // remove item from array or object and fill up gaps (if numeric keys are available) __remove_by_key([0 => 'foo', 1 => 'bar', 2 => 'baz'], 1) // [0 => 'foo', 1 => 'baz'] __remove_by_key(['foo' => 1, 'bar' => 2, 'baz' => 3], 'foo') // ['bar' => 2, 'baz' => 3] __remove_by_key((object)[0 => 'foo', 1 => 'bar', 2 => 'baz'], 1) // (object)[0 => 'foo', 1 => 'baz'] __remove_by_value([0 => 'foo', 1 => 'bar', 2 => 'baz'], 'bar') // [0 => 'foo', 1 => 'baz'] __remove_by_value(['foo' => 1, 'bar' => 2, 'baz' => 3], 1) // ['bar' => 2, 'baz' => 3] __remove_by_value((object)[0 => 'foo', 1 => 'bar', 2 => 'baz'], 'bar') // (object)[0 => 'foo', 1 => 'baz'] // get max array depth __arr_depth(['foo' => 'bar', 'bar' => ['baz' => ['gnarr' => 'gnaz']]]) // 3 // (conditional) append/prepend to array __arr_append(['foo'], 'bar') // ['foo','bar'] __arr_prepend(['bar'], 'foo') // ['foo','bar'] __arr_append(['foo'], 'bar', 42%7 === 0) // ['foo','bar'] __arr_prepend(['bar'], 'foo', 0%1 === 1) // ['foo'] __arr_append(__arr_append(__arr_append([], 'foo'), 'bar', false), 'baz') // ['foo','baz'] // turn values of array "inside out" // this is useful when working with html forms /* <li><input type="text" name="data[option1][]" /><input type="text" name="data[option2][]" /></li> <li><input type="text" name="data[option1][]" /><input type="text" name="data[option2][]" /></li> <li><input type="text" name="data[option1][]" /><input type="text" name="data[option2][]" /></li> <li><input type="text" name="data[option1][]" /><input type="text" name="data[option2][]" /></li> */ __inside_out_values([ 'option1' => [0 => 'foo', 1 => 'bar', 2 => 'baz', 3 => ''], 'option2' => [0 => 'bar', 1 => 'baz', 2 => 'foo', 3 => null] ]) /* [ 0 => ['option1' => 'foo','option2' => 'bar'], 1 => ['option1' => 'bar','option2' => 'baz'], 2 => ['option1' => 'baz','option2' => 'foo'] ] */ // converts recursively nested arrays into objects // this is useful when working with state in vue/redux // objects are automatically keyed by id (if property "id" is available) __arrays_to_objects(['foo' => ['bar','baz'], 'bar' => [(object)['id' => 7, 'name' => 'foo'], (object)['id' => 42, 'name' => 'bar']]]) // { 'foo': { 0: 'bar', 1: 'baz' }, 'bar' => { 7: { 'id': 7, 'name': 'foo' }, 7: { 'id': 42, 'name': 'bar' } } } // read/write data to arrays in dot notation __array_get(['foo'=>['bar'=>['baz'=>42]]], 'foo.bar.baz'); // 42 __array_set(['foo'=>['bar'=>['baz'=>42]]], 'foo.bar.baz', 7); // ['foo'=>['bar'=>['baz'=>7]]] // highlight strings __highlight('that is a search string', 'is') // that <strong class="highlight">is</strong> a search string __highlight('abc def geh ijk lmn opq rst abc def geh ijk lmn opq rst', 'ijk', true, 5) // '... geh <strong class="highlight">ijk</strong> lmn ... geh <strong class="highlight">ijk</strong> lmn ...' // checks if variable is an integer (accepts also well formed strings) __is_integer(0) // true __is_integer(42) // true __is_integer(4.2) // false __is_integer(0.42) // false __is_integer(42.) // true __is_integer('42') // true __is_integer('a42') // false __is_integer('42a') // false __is_integer(0x24) // true __is_integer(8372468764378627868742367883268) // true (in comparison to is_int()) __is_integer('8372468764378627868742367883268') // true __is_integer(' 1337') // false __is_integer('1337 ') // false __is_integer([]) // false __is_integer(null) // false __is_integer(false) // false __is_integer(true) // false // convert float to nice ratio __float_to_ratio(1920/600) // 16:5 __float_to_ratio(1/3) // 1:3 // output arguments in a reader friendly way __o($var) __o($var1, $var2, $var3) __o('<strong>foo</strong>') // html codes are not parsed: array(1) { [0]=> string(32) "<strong>foo</strong>" } // same as __o but die afterwards __d($var) // flatten multidimensional array (keys) __flatten_keys(['foo' => ['bar' => 'baz']]) // ['foo','bar'] // flatten multidimensional array (values) __flatten_values(['foo' => 'bar', 'bar' => ['baz', 'foo']]) // ['bar','baz','foo'] // get nth element of concatenized array __expl(' ', 'foo bar baz', 1) // bar __expl(' ', 'foo bar baz') // foo // redirect via php (following post/redirect/get-pattern) __prg() // to current url without get arguments __prg('https://test.de') // redirect via php/html __redirect_to() // to current url without get arguments __redirect_to('https://test.de') __redirect_to('https://test.de', 301) // with "Moved permanently" __redirect_to('https://test.de', 302) // with "Moved temporarily" __redirect_to('https://test.de', 7, 'html') // redirect in 7 seconds (via html) // show system messages // -- in your controller system_message('foo') system_message('bar', 'error') // -- in your view $system_messages = system_messages(); // must be before any output echo '<!DOCTYPE html><html lang="de"><body>'; foreach ($system_messages as $system_messages__value) { echo '<div class="system-message system-message--'.$system_messages__value->type.'">'; echo $system_messages__value->content; echo '</div>'; } echo '</body></html>'; // throw exceptions (with arrays as messages) try { __exception('foo'); } catch(\Throwable $t) { __exception_message($t) // 'foo' } try { __exception(['foo' => 'bar']); } catch(\Throwable $t) { __exception_message($t) // ['foo' => 'bar'] } try { throw new \Exception('bar'); } catch(\Throwable $t) { __exception_message($t) // 'bar' } // you also catch these specific exceptions only try { __exception('foo'); } catch(\ExtendedException $t) { __exception_message($t) // 'foo' } try { throw new \Exception('bar'); } catch(\ExtendedException $t) { // does not trigger } catch(\Exception $t) { // triggers } // success/error return values __success() // { success: true, message: '' } __error('missing data') // { success: false, message: 'missing data' } // simple hook system that supports actions/filters with priorities $GLOBALS['t'] = 0; __hook_fire('hook_name'); // $GLOBALS['t'] = 0 __hook_add('hook_name', function() { $GLOBALS['t']++; }); // $GLOBALS['t'] = 0 __hook_fire('hook_name'); // $GLOBALS['t'] = 1 __hook_fire('hook_name'); // $GLOBALS['t'] = 2 __hook_add('hook_name', function() { $GLOBALS['t'] *= 2; }); // $GLOBALS['t'] = 2 __hook_fire('hook_name'); // $GLOBALS['t'] = 6 __hook_fire('hook_name'); // $GLOBALS['t'] = 14 $foo = 1; __hook_add('filter_name', function($a) { return $a+1; }, 20); __hook_add('filter_name', function($a) { return $a*2; }, 10); __hook_add('filter_name', function($a) { return $a-3; }, PHP_INT_MAX); $foo = __hook_fire('filter_name', $foo); // $foo = 0 $foo = __hook_fire('filter_name', $foo); // $foo = -2 // get current os __os() // ['windows','mac','linux'] // get current url (without trailing slash) __url() // https://tld.com/foo/bar/baz.php?foo=bar (with get parameters) __urlWithoutArgs() // https://tld.com/foo/bar/baz.php (without get parameters) __baseurl() // https://tld.com __baseurl(true) // https://tld.com/foo/bar // compress image __image_compress('input.jpg') __image_compress('input.jpg', 70) __image_compress('input.jpg', 70, 'output.jpg') // fix exif image orientation __image_orientate('input.jpg') __image_orientate('input.jpg', 70) __image_orientate('input.jpg', 70, 'output.jpg') // get file extension from filename __file_extension('foo.jpg') // jpg // utf8 conversions __is_utf8('foo') // true; checks if a string is utf8 encoded __to_utf8('foo') // tries to convert any string to utf8 // drop-in replacements for deprecated utf8_encode/utf8_decode __utf8_encode('foo') __utf8_decode('foo') // read/write iptc tags (with full utf8 support) __iptc_codes() // returns important codes in human readable format: ['2#116' => 'Copyright', ...] __iptc_code('Copyright') // 2#116 __iptc_keyword('2#116') // Copyright __iptc_read('input.jpg') // ['2#116' => '© Copyright 2021 by foobar', ...] __iptc_read('input.jpg', '2#116') // '© Copyright 2021 by foobar __iptc_read('input.jpg', 'Copyright') // '© Copyright 2021 by foobar __iptc_write('input.jpg', ['2#116' => '© Copyright 2021 by foobar']) // this overwrites all existing data and only sets one field __iptc_write('input.jpg', '2#116', '© Copyright 2021 by foobar') // this only sets the specific field and leaves the rest intact __iptc_write('input.jpg', 'Copyright', '© Copyright 2021 by foobar') // also accepts human readable codes __iptc_write('input.jpg', 'Copyright', null) // delete specific tag __iptc_write('input.jpg', []) // reset all tags // poor mans encryption (via openssl) define('ENCRYPTION_KEY', '4736d52f85bdb63e46bf7d6d41bbd551af36e1bfb7c68164bf81e2400d291319') // first define your encryption key (generated with hash('sha256', uniqid(mt_rand(), true))) __decrypt(__encrypt('foo')) // 'foo' (hard, with individual one-time salt) __decrypt(__encrypt('bar','known_salt')) // 'bar' (soft, good for searching in dbs) // very poor mans encryption (via file system) define('ENCRYPTION_FOLDER', $_SERVER['DOCUMENT_ROOT'].'/encryption') // Deny from all this if this is public(!) __decrypt_poor(__encrypt_poor('foo')) // 'foo' $token = __encrypt_poor('bar') __decrypt_poor($token, true) // 'bar' (one time decryption supported) __decrypt_poor($token) // null // list all files in folder (['filename1','filename2',...]) __files_in_folder() // current folder __files_in_folder('.') // current folder __files_in_folder('foo') // subfolder __files_in_folder('foo', true) // do it recursively __files_in_folder('foo', true, ['.git', '.gitkeep']) // do it recursively and exclude some folders/files __files_in_folder('foo', true, ['.git', '.gitkeep'], true) // get absolute instead of relative paths // recursively remove folder and it's contents __rrmdir('foo') // zip/unzip __zip('output.zip', 'folder') __zip('output.zip', 'file1.jpg') __zip('output.zip', ['file1.jpg', 'subfolder/file2.jpg']) __zip('output.zip', ['file1.jpg', 'subfolder/file2.jpg'], true) // strips paths __unzip('output.zip', '.') // check if link is external or internal __is_external('https://github.com/vielhuber/stringhelper') // false __is_external('https://github.com/vielhuber/stringhelper/') // false __is_external('https://github.com/vielhuber/stringhelper/issues') // false __is_external('https://github.com/vielhuber/stringhelper/test.pdf') // true __is_external('tel:+4989215400142') // false __is_external('mailto:david@vielhuber.de') // false __is_external('https://vielhuber.de') // true __is_external('https://vielhuber.de/test.pdf') // true $_GET = ['page_id' => '13', 'code' => '<h1>Hello World!</h1>']; $_POST = ['foo' => 'bar', 42 => "\0"]; // fetch post/get variables if they exist __get('foo') // null (because not set) __get('page_id') // '13' __post('foo') // bar // filter get parameters from url __filter_url_args('https://ai?foo=bar&bar=baz&baz=foo', ['foo','bar']) // https://ai?baz=foo // clean up post/get from malicious content using filter_var_array __clean_up_get() // $_GET = ['page_id' => '13', 'code' => 'Hello World!'] __clean_up_post() // $_POST = ['foo' => 'bar', 42 => ''] __clean_up() // same as __clean_up_get() and __clean_up_post() // read .env file (poor mans version) __read_env('.env') // ['foo' => 'bar', 'bar' => 'baz'] // check for repetitive actions, e.g. to prevent mass spam mailing (based on hashed client ip address) __is_repetitive_action(); // any action __is_repetitive_action('name'); // specific action __is_repetitive_action('name', 60); // allow 1 action per 60 minutes (this is the default if not specified) __is_repetitive_action('name', 1/60); // allow 1 action per 1 second __is_repetitive_action('name', 60, ['127.0.0.1','0.0.0.0']); // whitelist ip addresses // check for spam words in string (blacklist blocker utilizing https://github.com/splorp/wordpress-comment-blacklist) __has_spamwords('This is cool stuff.') // false __has_spamwords('I do spy software your website.') // true __has_spamwords('Hongsheng Ltd') // false __has_spamwords('Hongsheng Ltd', ['hongsheng']) // true (add custom blacklist keywords) __has_spamwords('I do spy software your website.', null, ['spy software']) // false (add custom whitelist keywords) // check if ip is blacklisted on multiple dnsbls (dns based blackhole lists) __ip_is_on_spamlist('191.101.31.148') // true __ip_is_on_spamlist('127.0.0.1') // false // get referrer __referer() // $_SERVER['HTTP_REFERER'], if not available null // do simple get requests (via curl or as a fallback with php file_get_contents [allow_url_fopen=1]) __fetch('https://httpbin.org/anything') // { "method": "GET", ... } __fetch('https://httpbin.org/anything', 'curl') // { "method": "GET", ... } __fetch('https://httpbin.org/anything', 'php') // { "method": "GET", ... } // do curl requests (get/post) and get status code, body and header __curl( 'https://httpbin.org/anything', // url ['foo' => 'bar'], // data 'POST', // method ['Bar' => 'baz'], // headers false, // store and send cookies true, // send as json (or application/x-www-form-urlencoded) 60, // timeout in seconds ['username' => 'password'], // basic authentication ['foo' => 'bar'], // cookies true, // follow redirects 'username:password@192.168.178.1:8080' // use proxy (username, password and port are optional) ) __curl('https://httpbin.org/anything') // {"status": 200, "result": { "method": "GET", ... }, "headers": [ ... ], "url": "..."} __curl('https://httpbin.org/anything', ['foo' => 'bar'], 'POST') // {"status": 200, "result": { "method": "POST", "data": {"foo": "bar"}, ... }, "headers": [ ... ], "url": "..."} __curl('https://httpbin.org/anything', ['foo' => 'bar'], 'POST', ['Bar' => 'baz']) // {"status": 200, "result" => { "method": "POST", "headers" = { "Bar": "baz", ... }, ... }, "headers": [ ... ], "url": "..."} __curl('https://vielhuber.de') // json is automatically decoded (but only if the response is of type json) __curl('https://httpbin.org/anything', ['foo' => 'bar'], 'PUT') // {"status": 200, "result": { "method": "PUT", "data": {"foo": "bar"}, ... }, "headers": [ ... ], "url": "..."} __curl('https://httpbin.org/anything', null, 'DELETE') // {"status": 200, "result": { "method": "DELETE", "data": "", ... }, "headers": [ ... ], "url": "..."} // __curl also supports both storing and sending cookies (without leaving a trace on the local filesystem) // with that you can do cool stuff like scraping the wordpress backend __curl('https://vielhuber.de/wp-login.php', ['log' => 'username', 'pwd', 'password'], 'POST', null, true, false) __curl('https://vielhuber.de/wp-admin/options.php', null, 'GET', null, true) // you can also hijack the current browser session if logged in __curl('https://vielhuber.de/wp-admin/options.php', null, 'GET', null, false, false, 60, null, $_COOKIE) // mime type __get_mime_type('foo.png') // image/png __mime_type_to_extension('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') // 'xlsx' __extension_to_mime_types('xlsx') // ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel'] // reverse proxy __reverse_proxy('https://tld.com', [ '*' => [ 'replacements' => [ ['location.origin!==n.origin', '1===0&&location.origin!==n.origin'], /* simple replacements (like origin checks) */ ['/(https:\/\/.+\.example\.net\/assets\/js\/another\/asset.js)/', __urlWithoutArgs().'?url=$1'], /* regex is also possible */ ['</head>', '<style>.ads { display:none; }</style></head>'] /* dirty inject */ ], 'dom' => function($DOMDocument, $DOMXPath) { $DOMXPath->query('/html/body//*[@id="foo"]')[0]->setAttribute('data-bar','baz'); }, 'css' => '.ads { display:none; }', 'js' => 'alert("ok");' ], 'example.js' => [/*...*/], '/regex-match-v.*\.js/' => [/*...*/] ]) // full example require_once(__DIR__ . '/vendor/autoload.php'); if( !isset($_GET['url']) ) { echo '<!DOCTYPE html><head><title>proxy test</title></head><body> <iframe src="'.__urlWithoutArgs().'?url=https://www.wikipedia.org/" height="800" width="600"></iframe> </body></html>'; } else { __reverse_proxy($_GET['url'], [ '*' => [ 'replacements' => [ ['/(\/static|portal\/)/', __urlWithoutArgs().'?url=https://wikipedia.org/$1'], ], 'dom' => function($DOMDocument, $DOMXPath) { $el = $DOMDocument->createElement('marquee', ''); $el->nodeValue = 'Hello world.'; $DOMXPath->query('/html/body//*[@id="js-lang-list-button"]')[0]->appendChild($el); }, 'css' => '.pure-button { box-shadow: 0px 0px 20px 20px #f800ff }', 'js' => 'alert("proxied!");' ], '/l10n\/.+\.json/' => [ 'replacements' => [ ['Die freie Enzyklop\u00e4die', 'Die coole Enzyklop\u00e4die'] ], ] ]); } // check basic auth __has_basic_auth('https://vielhuber.de'); // false __has_basic_auth('https://httpbin.org/basic-auth/foo/bar'); // true __check_basic_auth('https://httpbin.org/basic-auth/foo/bar', 'foo','baz'); // false __check_basic_auth('https://httpbin.org/basic-auth/foo/bar', 'foo','bar'); // true // output json response with status code for apis __json_response([ 'success' => true, 'message' => 'successfully created object', 'public_message' => 'Object erfolgreich angelegt!', 'data' => [ 'id' => 42, 'foo' => 'bar' ], 200 // status code ]); // get input on backend (from x-www-form-urlencoded, application/json, ...) __input(); __input('specific-field'); __input('unknown-field', 'fallback'); // extract all urls of (potentially nested) remote sitemap __extract_urls_from_sitemap('https://vielhuber.de/sitemap_index.xml') // ['https://vielhuber.de','https://vielhuber.de/impressum/', ...] __extract_urls_from_sitemap('https://foo:bar@vielhuber.de/sitemap_index.xml') // supports basic auth __extract_urls_from_sitemap('https://vielhuber.de/sitemap_index.xml', 'foo:bar') __extract_urls_from_sitemap('https://vielhuber.de/sitemap_index.xml', null, true) // include lastmod parameter; [['url' => 'https://vielhuber.de', 'lastmod' => '2020-01-01 00:00:00'], ['url' => 'https://vielhuber.de/impressum/', 'lastmod' => '2020-01-01 00:00:00'], ...] // get meta tags from url __extract_title_from_url('https://vielhuber.de') // David Vielhuber > Full-Stack Developer aus München __extract_meta_desc_from_url('https://vielhuber.de') // 🌀 Vielhuber David ist ein Web-Geek mit einem Faible für schönes Design, einer Prise Perfektionismus und Augen für klare Konturen. 🌀 // extract youtube/vimeo video information from string __video_info('https://www.youtube.com/watch?v=WAZlcK7FUic') // ['id' => 'WAZlcK7FUic', 'provider' => 'youtube', 'thumbnail' => 'data:image/jpeg;base64,/9j/4AA...'] __video_info('https://vimeo.com/527316428') // ['id' => '527316428', 'provider' => 'vimeo', 'thumbnail' => 'data:image/jpeg;base64,/9j/4AA...'] __video_info('https://www.youtube.com/embed/WAZlcK7FUic?feature=oembed') // several different formats are accepted __video_info('WAZlcK7FUic') __video_info('527316428') __video_info('https://www.youtube.com/watch?v=WAZlcK7FUiZ') // null (strong id detection is also included) // char helpers for excel columns __char_to_int('D') // 4 __int_to_char(4) // 'D' __inc_char('D') // 'E' __inc_char('Z') // 'AA' __inc_char('A',2) // 'C' __dec_char('U') // 'T' // convert excel date timestamp to string and vice versa (be aware: excel does utc internally) __timestamp_excel_to_str(36526) // '2000-01-01 00:00:00' __timestamp_excel_to_str(36526.3440972222) // '2000-01-01 08:15:30' __timestamp_str_to_excel('01.01.2000') // 36526 __timestamp_str_to_excel('01.01.2000 08:15:30') // 36526.3440972222 // str_replace __str_replace_first('foo','bar','foofoo') // 'barfoo' __str_replace_last('foo','bar','foofoo') // 'foobar' // search/replace with regex __str_search_replace( ' foo_1_bar_2_baz_3_gnarr_4_gnaz foo_5_bar_6_baz_7_gnarr_8_gnaz foo_9_bar_10_baz_11_gnarr_12_gnaz ', '/foo_(.+)_bar_(?:.+)_baz_(.+)_gnarr_(.+)_gnaz/' , function($matches) { $matches[0]++; $matches[1]++; $matches[2]++; return $matches; } ) /* foo_2_bar_2_baz_4_gnarr_5_gnaz foo_6_bar_6_baz_8_gnarr_9_gnaz foo_10_bar_10_baz_12_gnarr_13_gnaz */ // fun with line endings __line_endings_convert($str, 'linux') // converts string to linux line endings (LF) __line_endings_convert($str, 'mac') // converts string to mac line endings (CR) __line_endings_convert($str, 'windows') // converts string to windows line endings (CRLF) __line_endings_weak_equals($str1, $str2) // compares 2 strings ignoring its line endings // inline text modifications using sed (also works on sed bsd) __sed_replace(['foo' => 'bar', 'bar' => 'baz', 'gna' => 'gnarr'], 'file.txt') __sed_prepend('foo', 'file.txt') __sed_append('bar', 'file.txt') // show diff of two strings __diff('foo bar baz', 'foo barz baz') // 2c2 // < bar // --- // > barz // csv fun __array2csv([['foo', 'bar', 'baz'],['foo', 'bar', 'baz']], 'file.csv') __array2csv([['foo', 'bar', 'baz'],['foo', 'bar', 'baz']], 'file.csv', ';', '"') __csv2array('file.csv') // [['foo', 'bar', 'baz'],['foo', 'bar', 'baz']] __csv2array('file.csv', ';', '"') // [['foo', 'bar', 'baz'],['foo', 'bar', 'baz']] // xml fun $arr = [ [ 'tag' => 'tag1', 'attrs' => ['attr1' => 'val1', 'attr2' => 'val2'], 'content' => [ [ 'tag' => 'tag2', 'attrs' => ['attr3' => 'val3', 'attr4' => 'val4'], 'content' => 'äöüß' ], [ 'tag' => 'tag3', 'attrs' => ['attr5' => 'val5', 'attr5' => 'val5'], 'content' => [ [ 'tag' => 'tag4', 'attrs' => ['attr6' => 'val6', 'attr7' => 'val7'], 'content' => 'äöüß' ] ] ] ] ] ]; $xml = '<?xml version="1.0" encoding="UTF-8"?> <tag1 attr1="val1" attr2="val2"> <tag2 attr3="val3" attr4="val4">äöüß</tag2> <tag3 attr5="val5"> <tag4 attr6="val6" attr7="val7">äöüß</tag4> </tag3> </tag1> '; __array2xml($arr); // $xml __array2xml($arr, 'file.xml'); // directly save to file __array2xml($arr, null, ['version' => '1.1']); // manually modify prolog attributes __array2xml($arr, null, null, true); // strip empty tags __xml2array('file.xml'); // $arr // measure performance __log_begin() for($i = 0; $i < 10000; $i++) { } __log_end() // echos script execution time __log_begin('task') for($i = 0; $i < 10000; $i++) { } $data = __log_end('task', false) // ['message' => '...', 'time' => '...']; __log_begin('task') for($i = 0; $i < 10000; $i++) { __log_begin('childtask') for($y = 0; $y < 100; $y++) { } __log_end('childtask') } __log_end('task') __log_begin('task1') __log_begin('task2') __log_end('task1') __log_end('task2') __log_begin() __log_begin() __log_end() // this ends latest entry (lifo) __log_end()
usage as class
if you don't like hotloaded functions, you also can use this library in a class-based way:
use vielhuber\stringhelper\__; __::x(42); // true
js implementation
there is also a javascript implemenation hlp with similiar functions available.
testing
copy .env.example
to .env
, fill in values, install dependencies with composer install
and run ./vendor/bin/phpunit
.
appendix
existence matrix
__x() | __true() | __false() | !== null | != null | !== false | != false | === true | == true | !is_null() | isset() | !empty() | if/else | ?true:false | (??true) === true | (??true) == true | (??true) === false | (??true) == false | count() > 0 | != '' | !== '' | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
null | false | false | false | false | false | true | false | false | false | false | false | false | false | false | true | true | false | false | false | false | true |
false | false | false | true | true | false | false | false | false | false | true | true | false | false | false | false | false | true | true | true | false | true |
true | true | true | false | true | true | true | true | true | true | true | true | true | true | true | true | true | false | false | true | true | true |
[] | false | false | false | true | false | true | false | false | false | true | true | false | false | false | false | false | false | false | false | true | true |
[''] | false | false | false | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
0 | true | false | true | true | false | true | false | false | false | true | true | false | false | false | false | false | false | false | true | false | true |
1 | true | true | false | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
-1 | true | true | false | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
'0' | true | false | true | true | true | true | false | false | false | true | true | false | false | false | false | false | false | false | true | true | true |
'1' | true | true | false | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
'-1' | true | true | false | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
'' | false | false | false | true | false | true | false | false | false | true | true | false | false | false | false | false | false | false | true | false | false |
' ' | false | false | false | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
'null' | true | false | false | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
'false' | true | false | true | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
'true' | true | true | false | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
'str' | true | true | false | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
[0,1] | true | true | false | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
[0] | true | true | false | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
'a:0:{}' | false | false | false | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
'b:1;' | true | true | false | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
'b:0;' | false | false | true | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
new stdClass | false | false | false | true | true | true | true | false | true | true | true | true | true | true | false | true | false | false | true | true | true |
$_GET['undefined'] | error | error | error | error | error | error | error | error | error | error | false | false | error | error | false | true | false | false | error | error | error |
@$_GET['undefined'] | false | false | false | false | false | true | false | false | false | false | false | false | false | false | true | true | false | false | false | false | true |
loose comparison matrix
== | null | false | true | [] | [''] | 0 | 1 | -1 | '0' | '1' | '-1' | '' | ' ' | 'null' | 'false' | 'true' | 'str' | [0,1] | [0] | 'a:0:{}' | 'b:1;' | 'b:0;' | new stdClass | $_GET['undefined'] | @$_GET['undefined'] |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
null | true | true | false | true | false | true | false | false | false | false | false | true | false | false | false | false | false | false | false | false | false | false | false | error | true |
false | true | true | false | true | false | true | false | false | true | false | false | true | false | false | false | false | false | false | false | false | false | false | false | error | true |
true | false | false | true | false | true | false | true | true | false | true | true | false | true | true | true | true | true | true | true | true | true | true | true | error | false |
[] | true | true | false | true | false | false | false | false | false | false | false | false | false | false | false | false | false | false | false | false | false | false | false | error | true |
[''] | false | false | true | false | true | false | false | false | false | false | false | false | false | false | false | false | false | false | true | false | false | false | false | error | false |
0 | true | true | false | false | false | true | false | false | true | false | false | true | true | true | true | true | true | false | false | true | true | true | error | error | true |
1 | false | false | true | false | false | false | true | false | false | true | false | false | false | false | false | false | false | false | false | false | false | false | error | error | false |
-1 | false | false | true | false | false | false | false | true | false | false | true | false | false | false | false | false | false | false | false | false | false | false | error | error | false |
'0' | false | true | false | false | false | true | false | false | true | false | false | false | false | false | false | false | false | false | false | false | false | false | false | error | false |
'1' | false | false | true | false | false | false | true | false | false | true | false | false | false | false | false | false | false | false | false | false | false | false | false | error | false |
'-1' | false | false | true | false | false | false | false | true | false | false | true | false | false | false | false | false | false | false | false | false | false | false | false | error | false |
'' | true | true | false | false | false | true | false | false | false | false | false | true | false | false | false | false | false | false | false | false | false | false | false | error | true |
' ' | false | false | true | false | false | true | false | false | false | false | false | false | true | false | false | false | false | false | false | false | false | false | false | error | false |
'null' | false | false | true | false | false | true | false | false | false | false | false | false | false | true | false | false | false | false | false | false | false | false | false | error | false |
'false' | false | false | true | false | false | true | false | false | false | false | false | false | false | false | true | false | false | false | false | false | false | false | false | error | false |
'true' | false | false | true | false | false | true | false | false | false | false | false | false | false | false | false | true | false | false | false | false | false | false | false | error | false |
'str' | false | false | true | false | false | true | false | false | false | false | false | false | false | false | false | false | true | false | false | false | false | false | false | error | false |
[0,1] | false | false | true | false | false | false | false | false | false | false | false | false | false | false | false | false | false | true | false | false | false | false | false | error | false |
[0] | false | false | true | false | true | false | false | false | false | false | false | false | false | false | false | false | false | false | true | false | false | false | false | error | false |
'a:0:{}' | false | false | true | false | false | true | false | false | false | false | false | false | false | false | false | false | false | false | false | true | false | false | false | error | false |
'b:1;' | false | false | true | false | false | true | false | false | false | false | false | false | false | false | false | false | false | false | false | false | true | false | false | error | false |
'b:0;' | false | false | true | false | false | true | false | false | false | false | false | false | false | false | false | false | false | false | false | false | false | true | false | error | false |
new stdClass | false | false | true | false | false | error | error | error | false | false | false | false | false | false | false | false | false | false | false | false | false | false | true | error | false |
$_GET['undefined'] | error | error | error | error | error | error | error | error | error | error | error | error | error | error | error | error | error | error | error | error | error | error | error | error | error |
@$_GET['undefined'] | true | true | false | true | false | true | false | false | false | false | false | true | false | false | false | false | false | false | false | false | false | false | false | error | true |