Wondering what’s next for npm?Check out our public roadmap! »

    isset-php

    1.0.6 • Public • Published

    isset-php

    Pipeline Status JavaScript Style Guide

    Safe and simple implementation of PHP isset() for JavaScript.

    Installation

    This is a zero dependency library that is safe from both ReferenceError: is not defined and TypeError: cannot read property of undefined exceptions.

    npm install --save isset-php

    Description

    TypeScript function signature:

    isset(accessor: Function, ...accessors: Function[]): boolean;

    Determine if a variable is considered set, this means if a variable is declared and is different than null or undefined.

    If a variable has been unset with the delete keyword, it is no longer considered to be set.

    isset() will return false when checking a variable that has been assigned to null or undefined. Also note that a null character ("\0") is not equivalent to the JavaScript null constant.

    If multiple parameters are supplied then isset() will return true only if all of the parameters are considered set. Evaluation goes from left to right and stops as soon as an unset variable is encountered.

    Parameters

    accessor
    Accessor function returning the variable to be checked.

    accessors
    Further accessor functions.

    Return Values

    Returns true if all accessors return a value that is not null or undefined. false otherwise.

    Examples

    Example #1 isset() Examples

    const isset = require('isset-php')
    let val = ''
    
    // This will evaluate to true so the text will be printed.
    if (isset(() => val)) {
      console.log('This val is set so I will print.')
    }
    
    // Less compact but still viable except when trying to use `this` context
    if (isset(function () { return val })) {
      console.log('This val is set so I will also print.')
    }

    In the next examples we'll use console.log() to output the return value of isset().

    let a = 'test'
    let b = 'anothertest'
    
    console.log(isset(() => a))            // true
    console.log(isset(() => a, () => b))   // true
    
    // This might throw a parsing error: Deleting local variable in strict mode
    delete a
    
    console.log(isset(() => a))            // false
    console.log(isset(() => a, () => b))   // false
    
    let foo = null
    
    console.log(isset(() => foo))          // false

    This also work for elements in objects:

    let a = { test: 1, hello: null, pie: { a: 'apple' } }
    
    console.log(isset(() => a.test))       // true
    console.log(isset(() => a.foo))        // false
    console.log(isset(() => a.hello))      // false
    
    // The key 'hello' equals null so is considered unset. If you want to check for
    // null key values then try:
    console.log(Object.prototype.hasOwnProperty.call(a, 'hello')) // true
    
    // Checking deeper object values
    console.log(isset(() => a.pie.a))      // true
    console.log(isset(() => a.pie.b))      // false
    console.log(isset(() => a.cake.a.b))   // false

    Example #2 isset() on String Offsets

    const expectedArrayGotString = 'somestring'
    
    console.log(isset(() => expectedArrayGotString.some_key))
    console.log(isset(() => expectedArrayGotString[0]))
    console.log(isset(() => expectedArrayGotString['0']))
    console.log(isset(() => expectedArrayGotString[0.5]))
    console.log(isset(() => expectedArrayGotString['0.5']))
    console.log(isset(() => expectedArrayGotString['0 Mostel']))

    Output of the above example in PHP 5.4 and above:

    false
    true
    true
    true  <-- PHP casts 0.5 to 0 for string offsets and throws a notice
    false
    false
    

    Output of the above example in JavaScript:

    false
    true
    true
    false <-- JS does not cast 0.5 to 0
    false
    false
    

    This is the only caveat with the JavaScript port as this behaviour is not emulated.


    Explanation

    Pulled from StackOverflow.

    PHP

    Note that in PHP you can reference any variable at any depth - even trying to access a non-array as an array will return a simple true or false:

    // Referencing an undeclared variable
    isset($some); // false
    
    $some = 'hello';
    
    // Declared but has no depth(not an array)
    isset($some); // true
    isset($some['nested']); // false
    
    $some = ['nested' => 'hello'];
    
    // Declared as an array but not with the depth we're testing for
    isset($some['nested']); // true
    isset($some['nested']['deeper']); // false

    JavaScript

    In JavaScript, we don't have that freedom, we'll always get an error if we do the same because JS is immediately attempting to access the value of deeper before we can wrap it in our isset() function so...

    // Common pitfall answer(ES6 arrow function)
    const isset = (ref) => typeof ref !== 'undefined'
    
    // Same as above
    function isset (ref) { return typeof ref !== 'undefined' }
    
    // Referencing an undeclared variable will throw an error, so no luck here
    isset(some) // Error: some is not defined
    
    // Defining a simple object with no properties - so we aren't defining
    // the property `nested`
    let some = {}
    
    // Simple checking if we have a declared variable
    isset(some) // true
    
    // Now trying to see if we have a top level property, still valid
    isset(some.nested) // false
    
    // But here is where things fall apart: trying to access a deep property
    // of a complex object; it will throw an error
    isset(some.nested.deeper) // Error: Cannot read property 'deeper' of undefined
    //         ^^^^^^ undefined

    More failing alternatives:

    // Any way we attempt to access the `deeper` property of `nested` will
    // throw an error
    some.nested.deeper.hasOwnProperty('value') // Error
    //   ^^^^^^ undefined
    
    // Similar to the above but safe from objects overriding `hasOwnProperty`
    Object.prototype.hasOwnProperty.call(some.nested.deeper, 'value') // Error
    //                                        ^^^^^^ undefined
    
    // Same goes for typeof
    typeof some.nested.deeper !== 'undefined' // Error
    //          ^^^^^^ undefined

    And some working alternatives that can get redundant fast:

    // Wrap everything in try...catch
    try {
      if (isset(some.nested.deeper)) {
        // ...
      }
    } catch (e) {}
    
    try {
      if (some.nested.deeper !== undefined && some.nested.deeper !== null) {
        // ...
      }
    } catch (e) {}
    
    // Or by chaining all of the isset which can get long
    isset(some) && isset(some.nested) && isset(some.nested.deeper) // false
    //                        ^^^^^^ returns false so the next isset() is never run

    Install

    npm i isset-php

    DownloadsWeekly Downloads

    218

    Version

    1.0.6

    License

    Apache-2.0

    Unpacked Size

    14.8 kB

    Total Files

    5

    Last publish

    Collaborators

    • avatar