Skip to content

Instantly share code, notes, and snippets.

@rolfen
Last active July 26, 2023 00:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rolfen/3cab714661106e2085578303b6b45e44 to your computer and use it in GitHub Desktop.
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.
<?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