STORAGE (רפרנס)

כל המתודות הציבוריות של המחלקה STORAGE - העלאת קבצים ותמונות, קריאה וכתובות, thumbnails ונגזרות, אחסון מרוחק (FTP ו-S3), ניקוי מטמון Cloudflare וזיהוי כפילויות.

⏱ 17 דק' קריאה 3026 מילים ערוך דף זה ב-GitHub

המחלקה STORAGE (system/collections/STORAGE.php) היא השכבה היחידה שכותבת וקוראת קבצים שהועלו דרך המערכת. כל קובץ הוא שורה בטבלה CRM_storage ועוד קובץ פיזי בתיקיית path, מקומית או מרוחקת. העמוד הזה הוא הרפרנס המלא של המתודות והמאפיינים; הסבר מושגי, יחד עם כללי אבטחה להעלאות, נמצא ב-STORAGE: העלאה ואחסון וב-כללי העלאת קבצים.

system/ בעמוד הזה הוא תיקיית הליבה הפרוסה (api/core בריפו), ו-{admin} הוא CONFIG::$admin_url.

מושגים שחשוב להכיר#

  • מזהה הקובץ בדיסק (get_file_identifier): כש-filename_type הוא uuid וקיים uuid בשורה, זה ה-uuid; אחרת זה ה-id. שם הקובץ הראשי הוא <identifier>.<ext>. עמודת name היא שם תצוגה בלבד ואינה חלק מהנתיב.
  • נגזרות (thumbnails, חיתוכים לפי יחס, watermark, blur) נשמרות באותה תיקייה בשם <identifier>_<key>.<ext>. רשימת המפתחות שנוצרו נשמרת בעמודה tumb בפורמט |key1||key2|. נגזרות אינן שורות ב-DB.
  • remote: עמודת remote היא "" או local (הקובץ תחת CONFIG::$base_path), ftp או s3. ברירת המחדל מגיעה מ-CONFIG::$storage_remote.
  • תיקיית temp: media/System/CropTmp (STORAGE::$temp_folder, יחסית). כל קריאה ל-add() מנקה ממנה קבצים בני יותר מ-5 שעות.
  • memo לבקשה: get($id) שומר את השורה בזיכרון עד סוף הבקשה (כולל תוצאה false). כל מתודה שכותבת קוראת ל-forget(). אם עדכנתם CRM_storage ב-SQL ישיר באותה בקשה, קראו ל-STORAGE::forget($id).

שדות מחושבים בשורה המוחזרת#

get() מוסיף לשורה שלושה שדות שלא קיימים ב-DB:

שדהתוכן
filenamename.ext
url_relpath/<identifier>.<ext>, יחסי לשורש האתר
urlכתובת אבסולוטית: CONFIG::$site_url . url_rel ל-local, CONFIG::$storage_remote_url/... ל-ftp, https://s3.amazonaws.com/... ל-s3

עמודות הטבלה#

עמודהנכתבת ע"ימשמעות
id, uuid, filename_typeaddמזהים ושיטת מתן שם לקובץ
name, ext, path, remote, dataaddשם תצוגה, סיומת (אותיות קטנות), תיקייה (ב-s3 מקודמת ב-bucket), מיקום, שדה חופשי
tumb, cropper_datasave_thumb_db, save_thumb, convert, replaceFromBase64רשימת נגזרות קיימות, ו-JSON של חיתוכים ידניים לפי יחס
object_type, object_id, ordaddשיוך לגלריה. object_id = -1 משמש לקבצים שהועלו לפני שנשמרה הרשומה שמחזיקה אותם
copyrights, description, folder_idaddקרדיט, טקסט חלופי, תיקייה וירטואלית (CRM_storage_folders)
file_hashadd, set_file_hashmd5 של התוכן אחרי המרה ושינוי גודל. נכתבת רק אם העמודה קיימת בטבלה
uploaded_byaddADMIN::get_id() כשהמעלה הוא מנהל

מאפיינים סטטיים#

מאפייןברירת מחדלמשמעות
STORAGE::$temp_folder"media/System/CropTmp"תיקיית temp יחסית ל-CONFIG::$base_path
STORAGE::$table"storage"שם הטבלה בלי CRM_ (אפשר לדרוס במחלקה יורשת)
STORAGE::$filename_type"uuid"שיטת מתן שם להעלאות חדשות: uuid או id
STORAGE::$gallery_max_width, $gallery_max_height, $gallery_convert_images, $gallery_require_copyrights, $gallery_require_descriptionfalseמגבלות להעלאות גלריה (ב-Tools::gallery_upload ובפאנל הקבצים)
STORAGE::$cloudfare_cache, $cloudfare_cache_zoneid, $cloudfare_cache_apikeyfalse, "", ""פרטי Cloudflare (האיות cloudfare הוא כך בקוד). purge_image פועל רק כש-zone ו-key לא ריקים
STORAGE::$default_jpeg_quality85איכות JPEG לכל עיבוד
STORAGE::$preserve_color_profiletrueנשמר לתאימות; בקוד הנוכחי הוא לא משנה את העיבוד
STORAGE::$use_imagick_for_qualitytrueשמירת חיתוכי JPEG דרך Imagick כשההרחבה קיימת

מפתחות הקונפיגורציה שהמחלקה קוראת מ-CONFIG_USER (פירוט ב-CONFIG_USER): storage_remote, storage_remote_url, storage_remote_ftp_host, storage_remote_ftp_username, storage_remote_ftp_password. פרטי S3 נקראים מ-MISC::$GLOBALS["Storage_remote_s3_key"], ["Storage_remote_s3_secret"] ו-["Storage_remote_s3_bucket"], ואין להם ברירת מחדל בליבה: האתר מגדיר אותם בקוד האתחול שלו (application/includes/init.php), ולעולם לא בתוך ריפו.

העלאה והסרה#

STORAGE::add($file_path, $opts = array())#

public static function add($file_path, $opts = array())

$file_path יכול להיות נתיב לקובץ מקומי, מערך $_FILES[...] (נלקחים tmp_name ו-name), או כתובת http(s):// (יורדת עם cURL, עוקבת אחרי הפניות, לקובץ זמני; clear נדלק אוטומטית).

אופציהברירת מחדלמשמעות
savetruetrue: נוצרת שורה ב-DB ומוחזר ה-id. false: נכתב רק הקובץ, בשם name המדויק, ומוחזר שם הקובץ. כך נוצרות נגזרות והחלפות תוכן
clearfalseלמחוק את קובץ המקור אחרי ההעלאה
path"media/Storage"תיקיית יעד. יחסית: תחת CONFIG::$base_path (local), תחת תיקיית ה-login (ftp), בתוך ה-bucket (s3)
remoteCONFIG::$storage_remote"", "ftp" או "s3"
nameשם הקובץ המקורי בלי סיומתעם save=true הוא עמודת name; עם save=false הוא שם הקובץ בדיסק
filename-שם מקורי מלא, משמש רק להסקת סיומת כש-$file_path חסר סיומת (כתובות URL)
filename_typeSTORAGE::$filename_typeuuid או id לשורה הזו
object_type, object_id""נכתבים רק אם שניהם לא ריקים
img_convert""jpg, png, gif או webp: המרת פורמט (Verot Upload). פורמט אחר, או קובץ שאינו תמונה, מחזיר false
img_max_width, img_max_height""הקטנה פרופורציונלית, רק אם התמונה גדולה מהמגבלה
img_width, img_height""גודל קבוע עם חיתוך (image_ratio_crop)
data, ord, copyrights, description, folder_id"", "", "", "", "0"נכתבים לעמודות המתאימות
s3_bucketMISC::$GLOBALS["Storage_remote_s3_bucket"] כש-storage_remote הוא s3נשמר כקידומת של path בטבלה

סדר הפעולות: ניקוי temp, זיהוי סיומת, חסימת סיומות, הורדה (אם URL), המרה, הקטנה, חיתוך לגודל קבוע, md5, שורת DB (אם save), העלאה ליעד, מחיקת המקור (אם clear). הסיומות החסומות: php, pl, py, cgi, asp, perl, php3 עד php7, pht, phtml, shtml, asa, cer, asax, xap, exe, html, js, css, htm. סיומת חסומה מסיימת את הבקשה עם die("STORAGE SECURITY ERROR!").

מחזירה: id חדש (save=true), שם קובץ (save=false), או false (כשל cURL, קובץ שאינו תמונה בעת המרה או הקטנה, המרה שנכשלה, העלאת FTP שנכשלה; במקרה האחרון השורה שנוצרה נמחקת כדי לא להשאיר יתום).

if (!empty($_FILES["photo"]["tmp_name"]))
{
    $sid = STORAGE::add($_FILES["photo"], [
        "path"          => "media/products",
        "object_type"   => "product",
        "object_id"     => (int)$productId,
        "img_convert"   => "webp",
        "img_max_width" => 1600,
        "clear"         => true,
    ]);
    if ($sid === false) { /* הקובץ לא תקין או שההעלאה נכשלה */ }
}
// ייבוא מכתובת חיצונית
$sid = STORAGE::add("https://example.com/images/hero.jpg", ["path" => "media/news", "name" => "hero"]);
שימו לב

החסימה היא לפי סיומת בלבד ברשימה שחורה, ללא בדיקת MIME. אל תסתמכו עליה כבדיקה היחידה: ודאו רשימת סיומות מותרות בצד הטופס, וראו כללי העלאת קבצים. בנוסף: (1) ייבוא מכתובת URL עוקב אחרי הפניות ולא חוסם כתובות פנימיות, ולכן אל תעבירו אליו כתובת שהמשתמש הקליד בלי בדיקה. (2) כשל בהעלאה ל-S3 (putObject) אינו נבדק ולא מוחק את השורה. (3) הקובץ מועלה ל-S3 עם ContentType: text/plain. (4) בענף ה-s3 אין break, והקוד ממשיך לענף ההעתקה המקומית, כך שיוצר גם עותק תחת CONFIG::$base_path/<path>. (5) המרה ושינוי גודל רצים בתוך הבקשה.

STORAGE::addFromBase64($base64, $name, $ext, $path, $remote = "local", $extra_settings = [])#

public static function addFromBase64($base64, $name, $ext, $path, $remote = "local", $extra_settings = [])

מקבלת base64 רגיל או data URI (data:image/png;base64,...). אם $ext ריק היא מוסקת מה-MIME של ה-data URI (jpeg הופך ל-jpg). כותבת קובץ temp וקוראת ל-add() עם name, ext, path, remote ועם $extra_settings (שגוברים). מחזירה כמו add(), או false אם הפענוח נכשל או ריק.

$sid = STORAGE::addFromBase64($dataUri, "avatar", "", "media/avatars", "local", ["img_max_width" => 512]);

STORAGE::replaceFromBase64($id, $base64)#

public static function replaceFromBase64($id, $base64)

מחליפה את תוכן הקובץ הקיים תחת אותו מזהה (אותה כתובת): מוחקת את הקובץ הישן והנגזרות הרשומות שלו (remove($file, true)), כותבת את החדש, מאפסת את tumb ומעדכנת ext לפי ה-data URI. מחזירה את השורה המעודכנת (get) או false.

STORAGE::remove($id, $only_files = false)#

public static function remove($id, $only_files = false)

מוחקת את השורה (אלא אם $only_files הוא true), את הקובץ הראשי ואת הנגזרות ששמן מתחיל ב-<identifier>_tumb_ או <identifier>_wtm_. ב-local המחיקה היא unlink ו-glob; ב-ftp ftp_delete לפי ftp_nlist; ב-s3 deleteMatchingObjects. אין ערך החזרה. $id יכול להיות גם שורה שכבר נשלפה.

שימו לב

נגזרות בשם לוגי (<identifier>_hero.jpg), חיתוכי יחס (<identifier>_<ratio>.jpg) וקבצי blur לא נמחקים ב-local, כי התבנית היחידה שנמחקת היא _tumb_*. הם נשארים יתומים בדיסק אחרי remove().

קריאה וכתובות#

STORAGE::get($id)#

public static function get($id)

$id מספרי: שורה מ-CRM_storage, מועשרת ב-filename, url_rel ו-url, או false אם אין. השורה נשמרת ב-memo של הבקשה. $id מערך: נחשב לשורה שכבר נשלפה, מועשר ומוחזר, בלי memo. כל ערך אחר מחזיר false.

$file = STORAGE::get((int)$row["image"]);
if ($file) echo '<img src="' . htmlspecialchars($file["url"]) . '" alt="' . htmlspecialchars($file["description"]) . '">';

STORAGE::get_all($object_type, $object_id, $ord = "ord ASC")#

static function get_all($object_type, $object_id, $ord = "ord ASC")

מחזירה מערך של שורות מועשרות (כמו get) של כל הקבצים ששויכו ל-object_type ול-object_id, בסדר $ord. זו הדרך לקרוא גלריה. השאילתה מבטלת את ה-join לטבלת התוכן הרב-לשונית (contentTable = "").

foreach (STORAGE::get_all("product", (int)$productId) as $img)
{
    echo STORAGE::get_thumb($img["id"], 300, 200);
}

STORAGE::get_url($id)#

public static function get_url($id)

מחזירה את url של הקובץ, או מחרוזת ריקה אם הוא לא קיים.

STORAGE::get_file_identifier($data)#

public static function get_file_identifier($data)

מקבלת שורה (מערך) ומחזירה את ה-uuid כש-filename_type הוא uuid והוא לא ריק, אחרת את ה-id. שורה בלי filename_type נחשבת ישנה ומחזירה id.

STORAGE::fileExists($id)#

public static function fileExists($id)

האם הקובץ הפיזי קיים בפועל: ב-local file_exists, ב-ftp בקשת HEAD לכתובת (true כשקוד התשובה קטן מ-400), ב-s3 doesObjectExist.

STORAGE::get_local_file($id, $name = false)#

public static function get_local_file($id, $name = false)

מחזירה נתיב לקובץ מקומי שאפשר לעבד: ב-local את url_rel, וב-ftp ו-s3 עותק שהורד לתיקיית temp (או false אם ההורדה נכשלה). עם $name מסוים, ואם הנגזרת הרשומה קיימת, מחזירה את הנגזרת. false אם הקובץ לא קיים.

הערה

בקבצים מרוחקים העותק בתיקיית temp הוא באחריות הקורא: הוא נמחק רק בניקוי הכללי של temp (אחרי 5 שעות).

STORAGE::get_temp_folder()#

public static function get_temp_folder()

מחזירה את הנתיב האבסולוטי של תיקיית temp: CONFIG::$base_path ועוד STORAGE::$temp_folder.

STORAGE::clear_tmp()#

public static function clear_tmp()

מוחקת מתיקיית temp קבצים שלא שונו מעל 5 שעות. add() קוראת לה בכל קריאה, ולכן אין צורך לקרוא לה ידנית.

STORAGE::forget($id = false)#

public static function forget($id = false)

מנקה מה-memo שורה אחת ($id), או את כולו (ללא פרמטר). קראו לה אחרי כל עדכון ישיר של CRM_storage.

STORAGE::set_filename_type($type)#

public static function set_filename_type($type)

קובעת את STORAGE::$filename_type להעלאות הבאות. ערך שאינו id או uuid מתעלמים ממנו בשקט.

Thumbnails ונגזרות#

STORAGE::get_thumb($id, $width = "auto", $height = "auto")#

public static function get_thumb($id, $width = "auto", $height = "auto")

מחזירה כתובת של נגזרת בגודל מבוקש. ערכים שאינם מספר חיובי הופכים ל-"auto". מפתח הנגזרת הוא tumb_<w>X<h>, והקובץ נקרא <identifier>_tumb_<w>X<h>.<ext>. ממד אחד בלבד: שינוי גודל פרופורציונלי. שני ממדים: שינוי גודל וחיתוך מדויק (image_ratio_crop). אם הנגזרת עוד לא נוצרה, היא נוצרת באותה בקשה. מחזירה "" אם הקובץ לא קיים, ואת כתובת המקור אם היצירה נכשלה או אם הסיומת אינה נתמכת (למשל svg). סיומות נתמכות לעיבוד: jpg, jpeg, png, webp.

$src  = STORAGE::get_thumb($row["image"], 400, 300);   // חיתוך ל-400x300
$wide = STORAGE::get_thumb($row["image"], 800);        // רוחב 800, גובה פרופורציונלי
שימו לב

נגזרות נוצרות בזמן הרינדור, באופן סינכרוני (set_time_limit(0), ignore_user_abort), כולל הורדה מ-FTP או S3 לקובץ מרוחק. עמוד עם 50 תמונות חדשות הוא 50 עיבודים בבקשה אחת. אפשר לקרוא ל-get_thumb מיד אחרי add() בשמירה, או לעטוף את הרינדור ב-cache_engine::get. הפונקציה גם לא בודקת שהקובץ קיים בדיסק, רק את עמודת tumb: אם מחקתם קבצים ידנית, אפסו את tumb. בנוסף, לפי קריאת הקוד, עבור gif הפונקציה הפנימית מחזירה את כתובת המקור (לא false), ולכן get_thumb מחזירה כתובת נגזרת שלא נוצרה. עבור gif השתמשו ב-get_url.

STORAGE::get_by_name($id, $name = "", $width = "auto", $height = "auto")#

public static function get_by_name($id, $name = "", $width = "auto", $height = "auto")

נגזרת בשם לוגי ("hero", "card"), למשל נגזרת של חיתוך ידני לפי יחס. false אם הקובץ לא קיים. אם $name ריק או "tumb", מוחזרת כתובת המקור. אם הנגזרת בשם הזה לא נרשמה בעמודה tumb, מוחזרת כתובת המקור (כשהממדים auto) או get_thumb($id, $width, $height). אחרת מוחזרת כתובת הנגזרת.

STORAGE::get_key_name($name = false, $width = "auto", $height = "auto")#

static function get_key_name($name = false, $width = "auto", $height = "auto")

מחשבת את מפתח הנגזרת: $name עצמו כשיש שם (שאינו tumb) ושני הממדים auto; אחרת <name>_<w>X<h>. ממד שאינו מספר חיובי הופך ל-auto.

STORAGE::is_exist($file, $key = "")#

static function is_exist($file, $key = "")

האם המפתח רשום בעמודת tumb של השורה $file (מערך). ללא $key נבדק $file["name"]. זו בדיקה בשורה בלבד: היא לא נוגעת בדיסק.

STORAGE::resize_image($file, $w, $h, $print_to_screen = true)#

public static function resize_image($file, $w, $h, $print_to_screen = true)

משנה גודל וחותך (image_ratio_crop) לגודל מדויק $w על $h, וכותב קובץ חדש בתיקיית temp. מחזירה את הנתיב לקובץ החדש, או כלום אם הקובץ לא נטען. $print_to_screen לא בשימוש.

STORAGE::getWatermark($id, $wk_file, $wk_left = 20, $wk_top = -20)#

public static function getWatermark($id, $wk_file, $wk_left = 20, $wk_top = -20)

מחזירה כתובת של נגזרת עם סימן מים ($wk_file הוא נתיב לתמונת הסימן, $wk_left ו-$wk_top מיקום) בשם <identifier>_wtm_<left>X<top>.<ext>. סיומות נתמכות: jpg, jpeg, png, gif; אחרת false.

שימו לב

הקוד בודק remote == "1" (ערך שהמערכת כבר לא כותבת), לא ftp או s3, ולכן הוא אמין רק לקבצים מקומיים. הבדיקה "האם הנגזרת קיימת" נעשית בלי מפתח, ולכן לפי קריאת הקוד היא עלולה לייצר את הנגזרת מחדש בכל קריאה. אל תשתמשו בה ברינדור של עמוד.

STORAGE::get_blur_image($id, $sigma = 13, $width = "auto", $height = "auto")#

public static function get_blur_image($id, $sigma = 13, $width = "auto", $height = "auto")

כתובת של גרסה מטושטשת (Imagick blurImage), אופציונלית אחרי שינוי גודל. נרשמת ב-tumb כ-blur<w>X<h>S<sigma>. שם הקובץ הוא MISC::encode של המחרוזת <identifier>_blur_<w>X<h>S<sigma>, ולא המחרוזת עצמה. false אם העיבוד נכשל או שהסיומת לא נתמכת. דורשת את ההרחבה Imagick.

STORAGE::save_thumb($sid, $ratio, $ratData)#

static function save_thumb($sid, $ratio, $ratData)

שומרת חיתוך ידני (מ-cropper.js): $ratData הוא אובייקט עם x, y, width, height, ו-$ratio שם היחס. כותבת <identifier>_<ratio>.<ext> ושומרת את הנתונים ב-cropper_data[$ratio]. מחזירה true כשנשמר, false כשהקובץ לא קיים או לא נטען, ו-null (בלי עבודה) כשהנתונים זהים למה ששמור או כשהסיומת אינה נתמכת.

STORAGE::save_thumb_db($sid, $ratio, $cropper_data = false)#

static function save_thumb_db($sid, $ratio, $cropper_data = false)

מוסיפה את $ratio לרשימת tumb (ומסירה ממנה ערך זהה או כזה שמתחיל ב-$ratio . "_"), ואם הועבר $cropper_data (מחרוזת JSON) כותבת גם אותו. אין ערך החזרה.

הערה
$cropper_data נכנס לשאילתה כמחרוזת כפי שהועברה. העבירו רק פלט של json_encode שיצרתם בעצמכם, ולעולם לא קלט גולמי של משתמש.

STORAGE::convert($sid, $type)#

static function convert($sid, $type)

ממירה את הקובץ הראשי לפורמט $type (ערכי Verot: jpg, png, gif, webp), מוחקת את הקובץ הישן והנגזרות, מעדכנת ext ומאפסת את tumb. מחזירה true (גם כשההמרה נכשלה בשקט) או כלום כשהקובץ לא נטען, ולכן אל תסתמכו על ערך ההחזרה כאישור; בדקו את ext בשורה.

אחסון מרוחק#

האחסון המרוחק נבחר לפי remote בכל שורה. המתודות למטה הן הציבוריות; החיבור עצמו (FtpConnect, Ftp_make_directory) פנימי.

STORAGE::FtpClose()#

static function FtpClose()

סוגרת את חיבור ה-FTP הפתוח (אם יש) ומאפסת את מצב החיבור. core.php קוראת לה בסוף כל בקשה, ולכן אין צורך לקרוא לה בקוד אתר. קריאה ידנית נחוצה רק בסקריפט ארוך שעבד מול FTP ולא עובר דרך core.php.

הערה

החיבור נפתח בעצלות בקריאה הראשונה ל-add או remove על קובץ ftp: עד 5 ניסיונות עם השהיה אקראית של 0.5 עד 1.5 שניות. אם אין חיבור, או שהכניסה נכשלה, הבקשה מסתיימת ב-die עם הודעת HTML. כלומר שרת FTP שלא זמין מפיל את הבקשה, ולא מחזיר false.

מלכודות של S3#

  • הספרייה היא AWS SDK ישן (Aws\S3\S3Client::factory, גרסה 2). היא נטענת ב-core.php רק כש-CONFIG::$storage_remote == "s3".
  • פרטי הגישה לא נבדקים לפני השימוש. אם MISC::$GLOBALS["Storage_remote_s3_*"] לא הוגדרו, הכשל יגיע מתוך ה-SDK.
  • ההעלאה היא ACL public-read ו-StorageClass REDUCED_REDUNDANCY.

מטמון Cloudflare#

STORAGE::purge_cloudflare_cache($files)#

public static function purge_cloudflare_cache($files)

שולחת בקשת purge ל-Cloudflare (POST /zones/<zone>/purge_cache) עבור כתובות מלאות. $files הוא מחרוזת או מערך; כפילויות וערכים ריקים מוסרים; הבקשות נשלחות במנות של עד 30 כתובות, עם timeout של 10 שניות. מחזירה true רק אם כל המנות החזירו הצלחה. מחזירה false אם אין כתובות או שה-zone או המפתח ריקים.

STORAGE::purge_image($ref)#

public static function purge_image($ref)

מנקה ב-CDN את הקובץ הראשי ואת כל הנגזרות הרשומות ב-tumb. $ref הוא id, uuid או שורה. מחזירה false בלי פעולה כשאין פרטי Cloudflare או שהקובץ לא נמצא. add() קוראת לה אחרי החלפת תוכן של קובץ קיים (save=false), ולכן קראו לה לפני איפוס tumb אם אתם מחליפים תוכן בעצמכם.

גיבוב וכפילויות#

STORAGE::set_file_hash($ref, $hash)#

public static function set_file_hash($ref, $hash)

כותבת md5 של התוכן על שורה קיימת. $ref הוא id או uuid של הקובץ הראשי (שם קובץ של נגזרת נדחה). $hash חייב להיות 32 תווי hex. מחזירה true כשנכתב, false כשה-hash לא תקין, השורה לא נמצאה או שהעמודה file_hash לא קיימת.

STORAGE::get_by_hash($hash, $exclude_id = 0)#

public static function get_by_hash($hash, $exclude_id = 0)

מחזירה מערך של כל השורות עם אותו file_hash (בלי הקובץ $exclude_id, אם הועבר). מערך ריק אם ה-hash לא תקין, אין כפילות, או שהעמודה לא קיימת. רשימה ריקה אחרי החרגת הקובץ שממנו שואלים פירושה שאין כפילות.

$hash = md5_file($tmpPath);
$dupes = STORAGE::get_by_hash($hash);
if ($dupes) { $existingId = $dupes[0]["id"]; }

ראו גם#

מצאתם טעות או חוסר? תקנו את הדף או פתחו Issue בריפו. התיעוד נכתב מתוך הקוד של ליבה 5.0.115.