Last active
November 29, 2017 02:57
-
-
Save kevindees/0dfe80fd5dfe22be2432b918e6223590 to your computer and use it in GitHub Desktop.
This is a code snippet of a framework I'm working on that I'm creating
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Autoload PSR4 Classes | |
* | |
* @param array $map map auto loaders, initializer, and class map to avoid file exists checks | |
* @param string|null $cache_prefix cache the init files as one file. | |
*/ | |
function autoload_psr4(array &$map = [], ?string $cache_prefix = null) { | |
if(isset($map['init']) && empty($cache_prefix) ) { | |
foreach ($map['init'] as $file) { | |
require $file; | |
} | |
} elseif( isset($map['init']) && !empty($cache_prefix) ) { | |
autoload_files_compress($map['init'], $cache_prefix, 1000); | |
} | |
spl_autoload_register(function ($class) use (&$map) { | |
if (isset($map['map'][$class])) { | |
require $map['map'][$class]; | |
return; | |
} | |
$prefix = $map['prefix']; | |
$folder = $map['folder']; | |
$len = strlen($prefix); | |
if (strncmp($prefix, $class, $len) !== 0) { return; } | |
$file = $folder . str_replace('\\', DIRECTORY_SEPARATOR, substr($class, $len)) . '.php'; | |
if ( is_file($file) ) { | |
require $file; | |
return; | |
} | |
}); | |
} | |
/** | |
* Cache File | |
* | |
* @param array $files | |
* @param string $prefix | |
* @param int $length | |
*/ | |
function autoload_files_compress( array $files, $prefix = 'app', $length = 20 ) { | |
$time = time(); | |
$path = path_files('cache/' . $prefix . '.cache.php' ); | |
if(is_file($path) ) { | |
$file_time = filemtime($path); | |
$length = $length * 60 + $file_time; | |
if( $time < $length) { | |
require $path; | |
return; | |
} | |
} | |
$cache = fopen($path, "w"); | |
fwrite($cache, '<?php'); | |
foreach ($files as $file) { | |
$data = file_get_contents($file); | |
$data = substr_replace( $data, '', strpos($data, '<?php'), 5 ); | |
$data = preg_replace('/(namespace\W*.*(?<!\;))\;/', '${1} {', $data, 1); | |
fwrite($cache, $data . PHP_EOL . '}'. PHP_EOL); | |
} | |
fclose($cache); | |
} | |
/** | |
* Get Constant Variable | |
* | |
* @param string $name the constant variable name | |
* @param null|mixed $default The default value | |
* | |
* @return mixed | |
*/ | |
function immutable($name, $default = null) { | |
return defined($name) ? constant($name) : $default; | |
} | |
/** | |
* Die and Dump | |
* | |
* Dump the variables and exit. | |
* | |
* @param array $params | |
*/ | |
function dd( ...$params ) { | |
call_user_func_array('var_dump', $params); | |
exit(); | |
} | |
/** | |
* Get Current Runtime | |
* | |
* @param bool $milliseconds get the run time in milliseconds | |
* | |
* @return mixed | |
*/ | |
function get_runtime($milliseconds = false ) { | |
$run = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']; | |
if( $milliseconds ) { return $run * 1000; } | |
return $run; | |
} | |
/** | |
* Resolve Class | |
* | |
* @param string $class | |
* | |
* @return object | |
* @throws \Exception | |
*/ | |
function resolve_class( string $class) | |
{ | |
$reflector = new \ReflectionClass($class); | |
if ( ! $reflector->isInstantiable()) { throw new \Exception($class . ' is not instantiable'); } | |
if ( ! $constructor = $reflector->getConstructor()) { return new $class; } | |
// Get Dependencies | |
$dependencies = []; | |
$parameters = $constructor->getParameters(); | |
// Auto Fill Parameters | |
foreach ($parameters as $parameter) { | |
if ( ! $dependency = $parameter->getClass()) { | |
if ($parameter->isDefaultValueAvailable()) { | |
$dependencies[] = $parameter->getDefaultValue(); | |
} else { | |
throw new \Exception('Cannot resolve no default for ' . $parameter->name . ' in ' . $class); | |
} | |
} else { | |
$dependencies[] = resolve_class($dependency->name); | |
} | |
} | |
return $reflector->newInstanceArgs($dependencies); | |
} | |
/** | |
* Resolve Call | |
* | |
* @param mixed $call the function or object map to resolve | |
* @param array $map the values to map parameters | |
* @param bool $stub create stub of class if found | |
* | |
* @return mixed | |
*/ | |
function resolve_method_args($call, $map = [], $stub = true) | |
{ | |
if(is_array($call)) { | |
$ref = new \ReflectionMethod($call[0], $call[1]); | |
} else { | |
$ref = new \ReflectionFunction($call); | |
} | |
$params = $ref->getParameters(); | |
$args = []; | |
foreach ($params as $param) { | |
$default = null; | |
$class = $param->getClass() ?? null; | |
if( $class ) { $class = resolve_class($class->getName()); } | |
if($param->isDefaultValueAvailable()) { $default = $param->getDefaultValue(); } | |
$param_name = $param->getName(); | |
$loaded_obj = isset($map[$param_name]) && is_object($map[$param_name]) ? $map[$param_name] : null; | |
$args[] = $loaded_obj ?? $class ?? $map[$param_name] ?? $default ?? null; | |
} | |
$method_map = ['args' => $args, 'method' => $ref, 'caller' => $call]; | |
if( $stub && $ref instanceof \ReflectionMethod ) { | |
if ( ! is_object($call[0]) ) { | |
$method_map['caller'][] = resolve_class($call[0]); | |
} else { | |
$method_map['caller'][] = $call[0]; | |
} | |
} | |
return $method_map; | |
} | |
/** | |
* Resolve Method Map | |
* | |
* @param $method_map | |
* | |
* @return mixed | |
*/ | |
function resolve_method_map($method_map) { | |
if( $method_map['method'] instanceof \ReflectionMethod ) { | |
return $method_map['method']->invokeArgs( $method_map['caller'][2], $method_map['args'] ); | |
} else { | |
return call_user_func_array($method_map['caller'], $method_map['args']); | |
} | |
} | |
function gen_args( string $gen ) { | |
if( strpos($gen, ',') !== false ) { | |
$args = []; | |
$segments = explode(',', $gen); | |
foreach ($segments as $segment) { | |
[$name, $value] = array_map('trim', explode(':', $segment, 2) ); | |
$args[$name] = $value; | |
} | |
return $args; | |
} | |
return null; | |
} | |
/** | |
* Emit HTTP Body | |
* | |
* @param mixed $value emit HTTP body from value | |
*/ | |
function echo_as_http_body($value) { | |
if( is_array($value) ) { | |
echo json_encode($value); | |
} elseif( is_object($value) && method_exists($value, 'echoAsHttpBody') ) { | |
$value->echoAsHttpBody(); | |
} elseif (is_string($value) ) { | |
echo $value; | |
} | |
} | |
/** | |
* Explode Path | |
* | |
* Explode a path accounting for Windows or Unix. | |
* | |
* @param string $path The input string such as a path | |
* @param int $limit negative starts with last positive start with first | |
* | |
* @return array | |
*/ | |
function explode_path( string $path, $limit = PHP_INT_MAX ) { | |
return explode(DIRECTORY_SEPARATOR, trim($path, DIRECTORY_SEPARATOR), $limit); | |
} | |
/** | |
* Explode URL | |
* | |
* @param string $path | |
* @param int $limit | |
* | |
* @return array | |
*/ | |
function explode_url_path( string $path, $limit = PHP_INT_MAX ) { | |
return explode('/', trim($path, '/'), $limit); | |
} | |
/** | |
* Dots Filter | |
* | |
* Traverse array with dot notation and filter the array. | |
* | |
* @param string $dots dot notation key.next.final or key.*.final | |
* @param array $array an array to traverse | |
* @param callable $callback a callback to filter matches | |
* @param bool $through only apply filter to last key in dots | |
* | |
* @return array|mixed | |
*/ | |
function dots_filter(string $dots, array $array, callable $callback, $through = true) : array { | |
$set = &$array; | |
$traverse = explode('.', $dots); | |
foreach($traverse as $step) { | |
array_shift($traverse); | |
if( $step === '*' && is_array($set) && !isset($indexes) ) { | |
$multi = &$set; | |
$indexes = array_keys($multi); | |
foreach($indexes as $index) { | |
if( is_array($multi[$index]) && !empty($traverse) ) { | |
$multi[$index] = dots_filter(implode('.', $traverse), $multi[$index], $callback, $through); | |
} elseif( empty($traverse) || $through === false ) { | |
$multi[$index] = call_user_func($callback, $multi[$index]); | |
} | |
} | |
} elseif( isset($set[$step]) && ! is_string($set) ) { | |
$set = &$set[$step]; | |
} | |
} | |
if(!isset($indexes)) { | |
$set = call_user_func($callback, $set); | |
} | |
return $array; | |
} | |
/** | |
* Dots Walk | |
* | |
* Traverse array with dot notation. | |
* | |
* @param string $dots dot notation key.next.final or key.*.final | |
* @param array $array an array to traverse | |
* @param null $default | |
* | |
* @return array|mixed|null | |
*/ | |
function dots_walk(string $dots, array $array, $default = null) { | |
$traverse = explode('.', $dots); | |
foreach ($traverse as $step) { | |
if( ! isset($array[$step]) && ! is_string($array) ) { return $default; } | |
$array = $array[$step]; | |
} | |
return $array; | |
} | |
/** | |
* Dots Meld | |
* | |
* Flatten array dimensions to one level and meld keys into dot | |
* notation. liken meld to ['key.child' => 'value']. | |
* | |
* @param array $array the values to meld | |
* | |
* @return array | |
*/ | |
function dots_meld(array $array) : array | |
{ | |
$iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($array)); | |
$result = []; | |
foreach ($iterator as $value) { | |
$keys = []; | |
$depth = range(0, $iterator->getDepth()); | |
foreach ($depth as $step) { | |
$keys[] = $iterator->getSubIterator($step)->key(); | |
} | |
$result[ implode('.', $keys) ] = $value; | |
} | |
return $result; | |
} | |
/** | |
* Dots Meld Process Regular Expression Filter | |
* | |
* Using a regular expression filter the matched array values | |
* matched using a callback. | |
* | |
* @param string $pattern the regular expression pattern | |
* @param array $array the original array | |
* @param callable $callback a callback to filter matches | |
* @param bool $expand return a multidimensional array by default | |
* | |
* @return array | |
*/ | |
function dots_meld_preg_filter($pattern, array $array, callable $callback, $expand = true) : array { | |
$melded = dots_meld($array); | |
foreach ($melded as $dots => $value) { | |
if(preg_match($pattern, $dots)) { | |
$melded[$dots] = call_user_func($callback, $value); | |
} | |
} | |
return $expand ? dots_meld_expand($melded) : $melded; | |
} | |
/** | |
* Dots Set | |
* | |
* Set an array value using dot notation. | |
* | |
* @param string $dots dot notation path to set | |
* @param array $array the original array | |
* @param mixed $value the value to set | |
* | |
* @return array | |
*/ | |
function dots_set(string $dots, array $array, $value) : array | |
{ | |
$set = &$array; | |
$traverse = explode('.', $dots); | |
foreach($traverse as $step) { | |
$set = &$set[$step]; | |
} | |
$set = $value; | |
return $array; | |
} | |
/** | |
* Dots Meld Expand | |
* | |
* Expand a dots melded array into a multi dimensional array. | |
* | |
* @param array $array dots melded array to expand | |
* | |
* @return array | |
*/ | |
function dots_meld_expand( array $array ) : array { | |
$expand = []; | |
foreach ($array as $dots => $value ) { | |
$traverse = explode('.', $dots); | |
$set = &$expand; | |
foreach ($traverse as $key) { | |
$set = &$set[$key]; | |
} | |
$set = $value; | |
} | |
return $expand; | |
} | |
/** | |
* Array Keys Exist | |
* | |
* @param array $search needle list of array keys to match | |
* @param array $array haystack array | |
* | |
* @return bool | |
*/ | |
function array_keys_exist(array $search, array $array) { | |
return count(array_intersect_key(array_flip($search), $array)) === count($search); | |
} | |
// Special Array Functions | |
function in_array_key($needle, $haystack, $key, $in = true) { | |
return isset($haystack[$key]) && ( in_array($needle, $haystack[$key] ) === $in); | |
} | |
function array_any_key( array $needle, $haystack, $flip = null) { | |
return array_intersect_key($haystack, $flip ? array_flip($needle) : $needle ); | |
} | |
/** | |
* String Ends | |
* | |
* @param $haystack | |
* @param $needle | |
* | |
* @return bool | |
*/ | |
function str_ends($haystack, $needle) | |
{ | |
$length = mb_strlen($needle); | |
if ($length == 0) { | |
return true; | |
} | |
return ( mb_substr($haystack, -$length ) === $needle ); | |
} | |
/** | |
* String Contains | |
* | |
* @param $haystack | |
* @param $needle | |
* | |
* @return bool | |
*/ | |
function str_contains($haystack, $needle) | |
{ | |
return ( mb_strpos( $haystack, $needle ) !== false ); | |
} | |
/** | |
* String Starts | |
* | |
* @param $haystack | |
* @param $needle | |
* | |
* @return bool | |
*/ | |
function str_starts($haystack, $needle) | |
{ | |
return mb_substr($haystack, 0, mb_strlen($needle) ) === $needle; | |
} | |
/** | |
* String Starts | |
* | |
* @param $haystack | |
* @param $needle | |
* | |
* @return bool | |
*/ | |
function str_starts_ascii($haystack, $needle) | |
{ | |
return substr($haystack, 0, strlen($needle) ) === $needle; | |
} | |
/** | |
* String Ends | |
* | |
* @param $haystack | |
* @param $needle | |
* | |
* @return bool | |
*/ | |
function str_ends_ascii($haystack, $needle ) | |
{ | |
$length = strlen($needle); | |
if ($length == 0) { return true; } | |
return ( substr($haystack, -$length ) === $needle ); | |
} | |
/** | |
* String Contains | |
* | |
* @param $haystack | |
* @param $needle | |
* | |
* @return bool | |
*/ | |
function str_contains_ascii($haystack, $needle) | |
{ | |
return ( strpos( $haystack, $needle ) !== false ); | |
} | |
// Browser Helpers | |
function browser_log($message) { | |
echo '<script>console.log("PHP Logs |> '.$message.'")</script>'; | |
} | |
function browser_alert($message) { | |
echo '<script>alert("PHP Alerts |> '.$message.'")</script>'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example of using blazing fast PSR autoloader:
Example of using some dots functions: