Last active
July 26, 2023 00:21
-
-
Save rolfen/3cab714661106e2085578303b6b45e44 to your computer and use it in GitHub Desktop.
A library of utility of generally useful PHP functions (filesystem, images, ini, text manipulation...). Outdated version of PHP.
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 | |
// ============ strings ================ | |
function smart_truncate($string, $limit, $break=" ", $pad="...") { | |
// truncates string to the first $break after $limit characters, then adds $pad to the end | |
// Original PHP code by Chirp Internet: www.chirp.com.au | |
// Please acknowledge use of this code by including this header. | |
// return with no change if string is shorter than $limit | |
$string = strip_tags($string); | |
if(strlen($string) <= $limit) return $string; | |
// is $break present between $limit and the end of the string? | |
if(false !== ($breakpoint = strpos($string, $break, $limit))) { | |
if($breakpoint < strlen($string) - 1) { | |
$string = substr($string, 0, $breakpoint) . $pad; | |
} | |
} | |
return $string; | |
} | |
function escape_js_string($string) { | |
// escapes single quotes and double quotes for use in generated javascript strings | |
return (str_replace(array("'",'"'), array('\x27','\x22'), $string)); | |
} | |
function suffix($string, $suffix) { | |
// sticks suffix to string if string is not empty | |
if (!empty($string)) { | |
return($string.$suffix); | |
} else { | |
return(""); | |
} | |
} | |
function try_vars() { | |
// returns first argument that is not empty | |
$args = func_get_args(); | |
foreach ($args as $arg) { | |
if(!empty($arg)) { | |
return($arg); | |
} | |
} | |
} | |
// ============= Image handling ============ | |
function constrain($imagedata, $size, $allow_upsize = true) { | |
// resize image, constraining image proportions inside $size[w] and $size[h] | |
extension_loaded('gd') or dl("php_gd2"); | |
if ($size['h'] == 0 or $size['w'] == 0) { | |
// avoid divide by 0 | |
trigger_error("Size cannot contain 0"); | |
return; | |
} | |
// load image | |
if(!empty($imagedata)) { | |
$image = imagecreatefromstring($imagedata); | |
if($image === false) { | |
// oops, not an image most probably | |
return; | |
} | |
} else { | |
trigger_error("Empty string when expecting image"); | |
return; | |
} | |
$src_width = imagesx($image); | |
$src_height = imagesy($image); | |
$src_ratio = $resizend_ratio = (float) 0; | |
$src_ratio = (float) $src_height / (float) $src_width; | |
$resized_ratio = (float) $size['h'] / (float) $size['w']; | |
$ref_axis = ($resized_ratio > $src_ratio) ? "w" : "h" ; | |
// calculate resize ratio | |
if ($ref_axis == 'w') { | |
if($allow_upsize or ($src_width > $size['w'])) { | |
$resized_width = $size['w']; | |
$resized_height = (int) ($size['w'] * $src_ratio); | |
} else { | |
$resized_width = $src_width; | |
$resized_height = $src_height; | |
} | |
} else { | |
if($allow_upsize or ($src_height > $size['h'])) { | |
$resized_height = $size['h']; | |
$resized_width = (int) ($size['h'] / $src_ratio); | |
} else { | |
$resized_width = $src_width; | |
$resized_height = $src_height; | |
} | |
} | |
$thumb = imagecreatetruecolor($resized_width, $resized_height); | |
imagecopyresampled($thumb, $image, 0, 0, 0, 0, $resized_width, $resized_height, $src_width, $src_height); | |
// if($allow_upscale or ($thumbwidth < $imagewidth) or ($thumbheight < $imageheight) ) { | |
// // generate thumbnail | |
// $thumb = imagecreatetruecolor($thumbwidth,$thumbheight); | |
// imagecopyresampled($thumb, $image, 0, 0, 0, 0, $size['x'], $size['y'], max($imagewidth, $size['x']), $imageheight); | |
// } else { | |
// // do not resize... | |
// $thumb = imagecreatetruecolor($imagewidth,$imageheight); | |
// imagecopyresampled($thumb, $image, 0, 0, 0, 0, $imagewidth, $imageheight, $imagewidth, $imageheight); | |
// } | |
// compress and return (imagejpeg() outputs to the browser, so we need to catch the output with ob_) | |
ob_start(); | |
if( imagejpeg($thumb, NULL, 85) ) { | |
$thumbdata = ob_get_contents(); | |
ob_end_clean(); | |
imagedestroy($image); | |
imagedestroy($thumb); | |
return $thumbdata; | |
} else { | |
ob_end_clean(); | |
} | |
} | |
function resize($imagedata, $thumbsize=90, $size_axis=false, $allow_upscale=false) | |
{ | |
// resizes image so that $size_axis == $thumbsize . If $size_axis is not properly set then it will pick the biggest of x,y | |
// possible values for $size_axis : 'x', 'y' (anything else is equivalent to "autodetection") | |
// by default, the function returns the original image if it finds that the resized image will be bigger (on both axis) then the original image, unless $allow_upscale is set | |
// $imagedata is a string containing the image binary data (can be of any type supported by gd2: jpeg, gif, etc..) | |
// function returns a string containing the binary data of the thumbnail compressed as JPEG, or false if something goes wrong. | |
extension_loaded('gd') or dl("php_gd2"); | |
// load image | |
$image = imagecreatefromstring($imagedata); | |
$imagewidth = imagesx($image); | |
$imageheight = imagesy($image); | |
// choose x or y axis | |
if ($size_axis!='x' and $size_axis!='y') { | |
// automatic detection of the biggest axis | |
if ( $imagewidth > $imageheight) { | |
$size_axis = 'x'; | |
} else { | |
$size_axis = 'y'; | |
} | |
} | |
// calculate resize ratio | |
if ($size_axis == 'x') { | |
// x is set | |
$thumbwidth = $thumbsize; | |
$factor = $thumbsize / $imagewidth; | |
$thumbheight = (int) ($imageheight * $factor); | |
} else { | |
// y is set | |
$thumbheight = $thumbsize; | |
$factor = $thumbsize / $imageheight; | |
$thumbwidth = (int) ($imagewidth * $factor); | |
} | |
if($allow_upscale or ($thumbwidth < $imagewidth) or ($thumbheight < $imageheight) ) { | |
// generate thumbnail | |
$thumb = imagecreatetruecolor($thumbwidth,$thumbheight); | |
imagecopyresampled($thumb, $image, 0, 0, 0, 0, $thumbwidth, $thumbheight, $imagewidth, $imageheight); | |
} else { | |
// do not resize... | |
$thumb = imagecreatetruecolor($imagewidth,$imageheight); | |
imagecopyresampled($thumb, $image, 0, 0, 0, 0, $imagewidth, $imageheight, $imagewidth, $imageheight); | |
} | |
// compress and return (imagejpeg() outputs to the browser, so we need to catch the output with ob_) | |
ob_start(); | |
if( imagejpeg($thumb) ) { | |
$thumbdata = ob_get_contents(); | |
ob_end_clean(); | |
imagedestroy($image); | |
imagedestroy($thumb); | |
return $thumbdata; | |
} else { | |
ob_end_clean(); | |
} | |
} | |
function crop($image, $width, $height, $start_width, $start_height, $scale){ | |
// scale is like a zoom. If it's 2, for example, every pixel in $image will result in 2 pixels in the returned image | |
// list($imagewidth, $imageheight, $imageType) = getimagesize($image); | |
$newImageWidth = ceil($width * $scale); | |
$newImageHeight = ceil($height * $scale); | |
$newImage = imagecreatetruecolor($newImageWidth,$newImageHeight); | |
$source = imagecreatefromstring($image); | |
imagecopyresampled($newImage,$source,0,0,$start_width,$start_height,$newImageWidth,$newImageHeight,$width,$height); | |
ob_start(); | |
if( imagejpeg($newImage) ) { | |
$imageData = ob_get_contents(); | |
ob_end_clean(); | |
return $imageData; | |
} else { | |
ob_end_clean(); | |
} | |
} | |
function get_height($image) { | |
$img = imagecreatefromstring($image); | |
return (imagesy($img)); | |
} | |
function get_width($image) { | |
$img = imagecreatefromstring($image); | |
return (imagesx($img)); | |
} | |
/* =========== HTTP ============== */ | |
function forceHttps() { | |
if(!$_SERVER['HTTPS']) { | |
header("HTTP/1.1 301 Moved Permanently"); | |
header("Location: https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); | |
die(); | |
} | |
} | |
// unsets empty arrays inside md arrays | |
function unset_empty (&$array){ | |
do { | |
$array_before = $array; | |
foreach($array as $key => $value) { | |
if (empty($value)) { | |
unset($array[$key]); | |
} else if (is_array($value)) { | |
$array[$key] = unset_empty($value); | |
} else { | |
$array[$key] = $value; | |
} | |
} | |
} while ($array_before != $array); | |
return($array); | |
} | |
function randstr($length=5) { | |
// random string of length $length | |
$ret = ""; | |
for ($i=0; $i<($length); $i++) { | |
$d=mt_rand(1,30)%2; | |
$ret .= $d ? chr(mt_rand(65,90)) : chr(mt_rand(48,57)); | |
} | |
return $ret; | |
} | |
function makeUrlQuery($args) { | |
// builds an URL query from key => value pairs | |
// (does not prepend "?" at the beginning) | |
$url = ""; | |
foreach($args as $key => $val) { | |
$url .= rawurlencode($key).'='.rawurlencode($val).'&'; | |
} | |
$url = rtrim($url, "&"); | |
return($url); | |
} | |
function array_merge_recursive_simple() { | |
// Recursive version of array_merge(). Does not do stupid append, unlike the native PHP array_merge_recursive(). | |
// variable arg list | |
if (func_num_args() < 2) { | |
trigger_error(__FUNCTION__ .' needs two or more array arguments', E_USER_WARNING); | |
return; | |
} | |
$arrays = func_get_args(); | |
$merged = array(); | |
while ($arrays) { | |
$array = array_shift($arrays); | |
if (!is_array($array)) { | |
trigger_error(__FUNCTION__ .' encountered a non array argument', E_USER_WARNING); | |
return; | |
} | |
if (!$array) | |
continue; | |
foreach ($array as $key => $value) | |
if (is_string($key)) | |
if (is_array($value) && array_key_exists($key, $merged) && is_array($merged[$key])) | |
$merged[$key] = call_user_func(__FUNCTION__, $merged[$key], $value); | |
else | |
$merged[$key] = $value; | |
else | |
$merged[] = $value; | |
} | |
return $merged; | |
} | |
function instanciate($records, $class_name) { | |
$objects = array(); | |
foreach($records as $record) { | |
$objects[] = new $class_name($record); | |
} | |
return($objects); | |
} | |
/* =========== filesystem functions ============== */ | |
function is_in_dir($dir, $filename, $recursive = false) { | |
// filename is found in $path? | |
$available_files = get_files($dir, null, true); | |
$found = in_array($filename, $available_files); | |
if (!$found and $recursive) { | |
// recurse until found | |
$subdirs = get_subdirs($subdir); | |
foreach($subdirs as $subdir) { | |
if(is_in_dir($subdir, $filename, true)) { | |
$found = true; | |
break; | |
} | |
} | |
} | |
return($found); | |
} | |
function get_files($path, $regex = null, $relative = false) { | |
// if relative is true, will only return the path relative to $path | |
/* usage example | |
foreach( get_files('img/work','/^kitabat_.+\.(jpg|jpeg|gif|png)$/') as $image ) { | |
echo "<img class=\"screenie\" src=\"$image\">"; | |
} | |
*/ | |
if (!is_dir($path)) { | |
trigger_error("Directory not found: $path", E_USER_ERROR); | |
return(false); | |
} | |
$d = dir($path); | |
$ret = array(); | |
while ( $entry = $d->read() ) { | |
$current = "$path/$entry"; | |
if (is_file($current) and ($entry != ".") and ($entry != "..") and (!isset($regex) or preg_match($regex, $entry )) ) { | |
if ($relative) { | |
$ret[]=$entry; | |
} else { | |
$ret[]=$current; | |
} | |
} | |
} | |
$d->close(); | |
return $ret; | |
} | |
function get_subdirs($path, $regex = null, $relative = false) { | |
$d = dir($path); | |
$ret = array(); | |
while ( $entry = $d->read() ) { | |
$current = "$path/$entry"; | |
if (is_dir($current) and ($entry != ".") and ($entry != "..") and (!isset($regex) or preg_match($regex, $entry )) ) { | |
if ($relative) { | |
$ret[]=$entry; | |
} else { | |
$ret[]=$current; | |
} | |
} | |
} | |
$d->close(); | |
return $ret; | |
} | |
function get_parent_dir($path) { | |
$tmp = explode("/", rtrim($path,"/")); | |
array_pop($tmp); | |
return implode("/", $tmp); | |
} | |
function get_filename ($path) { | |
$tmp = explode("/", rtrim($path,"/")); | |
return array_pop($tmp); | |
} | |
function get_path ($path) { | |
// removes the filename component, returs the rest | |
return pathinfo ( $path, PATHINFO_DIRNAME ); | |
} | |
function filename_explode($filename) { | |
$tmp = explode(".", $filename); | |
$extension = array_pop($tmp); | |
$basename = implode(".", $tmp); | |
return (array($basename, $extension)); | |
} | |
function recurse_copy($src,$dst) { | |
$dir = opendir($src); | |
@mkdir($dst); | |
while(false !== ( $file = readdir($dir)) ) { | |
if (( $file != '.' ) && ( $file != '..' )) { | |
if ( is_dir($src . '/' . $file) ) { | |
recurse_copy($src . '/' . $file,$dst . '/' . $file); | |
} | |
else { | |
copy($src . '/' . $file,$dst . '/' . $file); | |
} | |
} | |
} | |
closedir($dir); | |
} | |
function recurse_rmdir($dir) { | |
// Dangerous! | |
// remove all files and directories, and recurse subdirectories | |
if (!empty($dir) and is_dir($dir)) { | |
$objects = scandir($dir); | |
foreach ($objects as $object) { | |
if ($object != "." && $object != "..") { | |
if (filetype($dir."/".$object) == "dir") { | |
recurse_rmdir($dir."/".$object); | |
} else { | |
unlink($dir."/".$object); | |
} | |
} | |
} | |
reset($objects); | |
rmdir($dir); | |
} | |
} | |
/* Here`s a small and easy write ini from array function...*/ | |
function read_ini_file($file) { | |
// return parse_ini_file($file, false, INI_SCANNER_NORMAL); | |
$ini = parse_ini_file($file); | |
$ret = array(); | |
foreach ($ini as $key => $option) { | |
$ret[$key] = str_replace('[DblQuot@]', '"', $option); | |
} | |
return $ret; | |
} | |
function write_ini_file($file, $array) | |
{ | |
$res = array(); | |
foreach($array as $key => $val) | |
{ | |
if(is_array($val)) | |
{ | |
$res[] = "[$key]"; | |
foreach($val as $skey => $sval) { | |
if (is_numeric($sval)) { | |
$res[] = "$skey = $sval"; | |
} else { | |
// escaped double quotes are not accepted | |
$sval = str_replace('"', '[DblQuot@]', $sval); | |
$res[] = "$skey = \"$sval\" "; | |
} | |
} | |
} | |
else { | |
if (is_numeric($val)) { | |
$res[] = "$key = $val"; | |
} else { | |
// escaped double quotes are not accepted | |
$val = str_replace('"', '[DblQuot@]', $val); | |
$res[] = "$key = \"$val\" "; | |
} | |
} | |
} | |
safefilerewrite($file, implode("\r\n", $res)); | |
} | |
function safefilerewrite($fileName, $dataToSave) | |
{ if ($fp = fopen($fileName, 'w')) | |
{ | |
$startTime = microtime(); | |
do | |
{ | |
$canWrite = flock($fp, LOCK_EX); | |
// If lock not obtained sleep for 0 - 100 milliseconds, to avoid collision and CPU load | |
if(!$canWrite) usleep(round(rand(0, 100)*1000)); | |
} while ((!$canWrite)and((microtime()-$startTime) < 1000)); | |
//file was locked so now we can store information | |
if ($canWrite) | |
{ | |
fwrite($fp, $dataToSave); | |
flock($fp, LOCK_UN); | |
} | |
fclose($fp); | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment