UNPKG

locutus

Version:

Locutus other languages' standard libraries to JavaScript for fun and educational purposes

59 lines (58 loc) 2.28 kB
import { resolvePhpCallable } from "../_helpers/_callbackResolver.js"; import { getPhpGlobalEntry, getPhpObjectEntry } from "../_helpers/_phpRuntimeState.js"; import { isObjectLike, isPhpCallable, } from "../_helpers/_phpTypes.js"; export function call_user_func_array(cb, parameters) { // discuss at: https://locutus.io/php/call_user_func_array/ // original by: Thiago Mata (https://thiagomata.blog.com) // revised by: Jon Hohle // improved by: Brett Zamir (https://brett-zamir.me) // improved by: Diplom@t (https://difane.com/) // improved by: Brett Zamir (https://brett-zamir.me) // note 1: Callback resolution intentionally avoids eval/new Function for security. // example 1: call_user_func_array('isNaN', ['a']) // returns 1: true // example 2: call_user_func_array('isNaN', [1]) // returns 2: false let func; let scope = null; try { const resolved = resolvePhpCallable(cb, { invalidMessage: 'invalid' }); func = resolved.fn; scope = resolved.scope; } catch { // Fall back to legacy-compatible callback resolution paths below. } if (!func && typeof cb === 'string') { const globalCandidate = getPhpGlobalEntry(cb); if (isPhpCallable(globalCandidate)) { func = globalCandidate; } } else if (!func && Array.isArray(cb)) { if (typeof cb[0] === 'string') { const globalScope = getPhpGlobalEntry(cb[0]); if (isObjectLike(globalScope) || typeof globalScope === 'function') { const method = getPhpObjectEntry(globalScope, String(cb[1])); if (isPhpCallable(method)) { func = method; } scope = globalScope; } } else if (isObjectLike(cb[0]) || typeof cb[0] === 'function') { const method = getPhpObjectEntry(cb[0], String(cb[1])); if (isPhpCallable(method)) { func = method; } scope = cb[0]; } } else if (!func && isPhpCallable(cb)) { func = cb; } if (!func) { throw new Error(String(cb) + ' is not a valid function'); } return func.apply(scope, parameters); }