programing

자바스크립트에서 PHP 배열을 비활성화합니다.

codeshow 2023. 9. 9. 10:20
반응형

자바스크립트에서 PHP 배열을 비활성화합니다.

요청하여 전달할 직렬 배열 행이 많은 테이블이 있습니다.JavaScript.

문제는 - 가능할까요?unserializePHP 보다는 자바스크립트로?

그렇지 않으면 저는 모든 행을 로드하고, 루프하고, 직렬 해제하여 임시 PHP 배열에 할당한 다음 json_encode해야 하는데, 이는 자바스크립트가 필요할 때 데이터를 직렬 해제할 수 있도록 데이터를 보낼 수 있다면 매우 비효율적으로 보입니다.

자바스크립트에 내장된 함수가 있습니까? 아니면 인코딩하기 전에 PHP의 행을 루프해야 합니까?

참고로 저는 jQuery를 사용하지 않습니다.

EDIT: 테이블에서 PHP로 직렬화된 데이터의 예:

a:8:{i:0;a:2:{i:0;i:10;i:1;i:11;}i:1;a:2:{i:0;i:9;i:1;i:11;}i:2;a:2:
{i:0;i:8;i:1;i:11;}i:3;a:2:{i:0;i:8;i:1;i:10;}i:4;a:2:{i:0;i:8;i:1;i:9;}i:5;a:2:
{i:0;i:8;i:1;i:8;}i:6;a:2:{i:0;i:8;i:1;i:7;}i:7;a:2:{i:0;i:8;i:1;i:6;}}

Php.js는 unserialize와 serialize의 자바스크립트 구현을 가지고 있습니다.

http://phpjs.org/functions/unserialize/

http://phpjs.org/functions/serialize/

그렇기는 하지만, 서버 쪽에서는 JSON으로 전환하는 것이 더 효율적일 것입니다.JSON.parse는 PHP.js의 Unserialize보다 훨씬 더 빠를 것입니다.

저는 PHP로 직렬화된 데이터를 역직렬화할 수 있는 JS 기능을 써보고 싶다고 생각했습니다.

그러나 이 솔루션을 사용하기 전에 다음 사항을 숙지하시기 바랍니다.

  • PHP에서 제작한 포맷.serialize기능은 PHP에 따라 다르므로 최선의 선택은 PHP의 것을 사용하는 것입니다.unserialize일을 제대로 하고 있다는 것을 100% 보장합니다.
  • PHP는 클래스 정보를 이러한 문자열에 저장할 수 있으며 일부 사용자 지정 직렬화 방법의 출력도 저장할 수 있습니다.따라서 이러한 문자열을 비순서화하려면 해당 클래스와 메서드에 대해 알아야 합니다.
  • PHP 데이터 구조는 자바스크립트 데이터 구조와 1 대 1로 대응하지 않습니다. PHP 연관 배열은 문자열을 키로 가질 수 있으므로 JS 배열보다는 자바스크립트 객체처럼 보이지만 PHP에서는 키가 삽입 순서를 유지하고 키는 JS 객체에서는 불가능한 진정한 숫자 데이터 유형을 가질 수 있습니다.그렇게 말할 수도 있습니다. 그러면 우리가 봐야 할 것 같습니다.MapJS에는 객체가 있지만, 이 객체들은 13과 "13"을 별도의 키로 저장할 수 있으며, PHP는 이를 허용하지 않습니다.우린 빙산의 일각을 건드리고 있을 뿐입니다
  • PHP는 객체의 보호된 속성과 개인 속성을 직렬화하는데, 이것은 이상할 뿐만 아니라(얼마나 개인적인 것입니까?) JS에는 아직 존재하지 않는 개념이거나, 적어도 같은 방식으로는 존재하지 않습니다.만약 어떤 사람이 어떻게든 JS에서 (하드) 사유 재산을 구현한다면, 어떤 비직렬화가 어떻게 그러한 사유 재산을 설정할 수 있을까요?
  • JSON은 PHP에 특화되지 않은 대안이며, 커스텀 클래스에 대해서도 신경 쓰지 않습니다.만약 당신이 직렬화가 이루어지면 의 PHP 소스에 접근할 수 있다면, 대신 JSON을 생산하도록 이것을 변경하세요.는 PHP를 제공합니다json_encode, 자바스크립트는고,해를 가지고 .JSON.parse 입니다.이것은 당신이 할 수 있다면 분명히 가야할 길입니다.

이러한 발언을 통해 여전히 J sunserialise 함수의 필요성이 느껴진다면 다음을 읽으십시오.

에 에 을 하는 이 JS 를 하는 JS .PHP공과한의체eshsrt본한-공t과n와JSON체:parse그리고.stringify.

에 이 에 대한 입력이 있을 때parse메서드는 클래스를 참조합니다. 그러면 먼저 (선택 사항) 두 번째 인수에서 해당 클래스에 대한 참조를 전달했는지 확인합니다.그렇지 않은 경우, 원하지 않는 부작용을 방지하기 위해 해당 클래스에 대한 모의가 생성됩니다.두 경우 모두 해당 클래스의 인스턴스가 생성됩니다.입력 문자열이 사용자 지정 직렬화를 지정하는 경우 메서드unserialize해당 개체 인스턴스가 호출됩니다.문자열 자체가 해당 작업을 수행하는 방법에 대한 정보를 제공하지 않으므로 이 방법으로 논리를 제공해야 합니다.해당 문자열을 생성한 PHP 코드에서만 알 수 있습니다.

이 구현은 순환 참조도 지원합니다.연관 배열이 순차 배열로 판명되면 JS 배열이 반환됩니다.

const PHP = {
    stdClass: function() {},
    stringify(val) {
        const hash = new Map([[Infinity, "d:INF;"], [-Infinity, "d:-INF;"], [NaN, "d:NAN;"], [null, "N;"], [undefined, "N;"]]); 
        const utf8length = str => str ? encodeURI(str).match(/(%.)?./g).length : 0;
        const serializeString = (s,delim='"') => `${utf8length(s)}:${delim[0]}${s}${delim[delim.length-1]}`;
        let ref = 0;
        
        function serialize(val, canReference = true) {
            if (hash.has(val)) return hash.get(val);
            ref += canReference;
            if (typeof val === "string") return `s:${serializeString(val)};`;
            if (typeof val === "number") return  `${Math.round(val) === val ? "i" : "d"}:${(""+val).toUpperCase().replace(/(-?\d)E/, "$1.0E")};`;
            if (typeof val === "boolean") return  `b:${+val};`;
            const a = Array.isArray(val) || val.constructor === Object;
            hash.set(val, `${"rR"[+a]}:${ref};`);
            if (typeof val.serialize === "function") {
                return `C:${serializeString(val.constructor.name)}:${serializeString(val.serialize(), "{}")}`;
            }
            const vals = Object.entries(val).filter(([k, v]) => typeof v !== "function");
            return (a ? "a" : `O:${serializeString(val.constructor.name)}`) 
                + `:${vals.length}:{${vals.map(([k, v]) => serialize(a && /^\d{1,16}$/.test(k) ? +k : k, false) + serialize(v)).join("")}}`;
        }
        return serialize(val);
    },
    // Provide in second argument the classes that may be instantiated
    //  e.g.  { MyClass1, MyClass2 }
    parse(str, allowedClasses = {}) {
        allowedClasses.stdClass = PHP.stdClass; // Always allowed.
        let offset = 0;
        const values = [null];
        const specialNums = { "INF": Infinity, "-INF": -Infinity, "NAN": NaN };

        const kick = (msg, i = offset) => { throw new Error(`Error at ${i}: ${msg}\n${str}\n${" ".repeat(i)}^`) }
        const read = (expected, ret) => expected === str.slice(offset, offset+=expected.length) ? ret 
                                         : kick(`Expected '${expected}'`, offset-expected.length);
        
        function readMatch(regex, msg, terminator=";") {
            read(":");
            const match = regex.exec(str.slice(offset));
            if (!match) kick(`Exected ${msg}, but got '${str.slice(offset).match(/^[:;{}]|[^:;{}]*/)[0]}'`);
            offset += match[0].length;
            return read(terminator, match[0]);
        }
        
        function readUtf8chars(numUtf8Bytes, terminator="") {
            const i = offset;
            while (numUtf8Bytes > 0) {
                const code = str.charCodeAt(offset++);
                numUtf8Bytes -= code < 0x80 ? 1 : code < 0x800 || code>>11 === 0x1B ? 2 : 3;
            }
            return numUtf8Bytes ? kick("Invalid string length", i-2) : read(terminator, str.slice(i, offset));
        }
        
        const create = className => !className ? {}
                    : allowedClasses[className] ? Object.create(allowedClasses[className].prototype)
                    : new {[className]: function() {} }[className]; // Create a mock class for this name
        const readBoolean = () => readMatch(/^[01]/, "a '0' or '1'", ";");
        const readInt     = () => +readMatch(/^-?\d+/, "an integer", ";");
        const readUInt    = terminator => +readMatch(/^\d+/, "an unsigned integer", terminator);
        const readString  = (terminator="") => readUtf8chars(readUInt(':"'), '"'+terminator);
        
        function readDecimal() {
            const num = readMatch(/^-?(\d+(\.\d+)?(E[+-]\d+)?|INF)|NAN/, "a decimal number", ";");
            return num in specialNums ? specialNums[num] : +num;
        }
        
        function readKey() {
            const typ = str[offset++];
            return typ === "s" ? readString(";") 
                 : typ === "i" ? readUInt(";")
                 : kick("Expected 's' or 'i' as type for a key, but got ${str[offset-1]}", offset-1);
        }
       
        function readObject(obj) {
            for (let i = 0, length = readUInt(":{"); i < length; i++) obj[readKey()] = readValue();
            return read("}", obj);
        }
        
        function readArray() {
            const obj = readObject({});
            return Object.keys(obj).some((key, i) => key != i) ? obj : Object.values(obj);
        }
        
        function readCustomObject(obj) {
            if (typeof obj.unserialize !== "function") kick(`Instance of ${obj.constructor.name} does not have an "unserialize" method`);
            obj.unserialize(readUtf8chars(readUInt(":{")));
            return read("}", obj);
        }
        
        function readValue() {
            const typ = str[offset++].toLowerCase();
            const ref = values.push(null)-1;
            const val = typ === "n" ? read(";", null)
                      : typ === "s" ? readString(";")
                      : typ === "b" ? readBoolean()
                      : typ === "i" ? readInt()
                      : typ === "d" ? readDecimal()
                      : typ === "a" ? readArray()                            // Associative array
                      : typ === "o" ? readObject(create(readString()))       // Object
                      : typ === "c" ? readCustomObject(create(readString())) // Custom serialized object
                      : typ === "r" ? values[readInt()]                      // Backreference
                      : kick(`Unexpected type ${typ}`, offset-1);
            if (typ !== "r") values[ref] = val;
            return val;
        }
        
        const val = readValue();
        if (offset !== str.length) kick("Unexpected trailing character");
        return val;
    }
}
/**************** EXAMPLE USES ************************/

// Unserialize a sequential array
console.log(PHP.parse('a:4:{i:0;s:4:"This";i:1;s:2:"is";i:2;s:2:"an";i:3;s:5:"array";}'));

// Unserialize an associative array into an object
console.log(PHP.parse('a:2:{s:8:"language";s:3:"PHP";s:7:"version";d:7.1;}'));

// Example with class that has custom serialize function:
var MyClass = (function () {
    const priv = new WeakMap(); // This is a way to implement private properties in ES6
    return class MyClass {
        constructor() {
            priv.set(this, "");
            this.wordCount = 0;
        }
        unserialize(serialised) {
            const words = PHP.parse(serialised);
            priv.set(this, words);
            this.wordCount = words.split(" ").length;
        }
        serialize() {
            return PHP.stringify(priv.get(this));
        }
    }
})();

// Unserialise a PHP string that needs the above class to work, and will call its unserialize method
// The class needs to be passed as object key/value as second argument, so to allow this side effect to happen:
console.log(PHP.parse('C:7:"MyClass":23:{s:15:"My private data";}', { MyClass } ));

json_encodeunserialize

echo json_encode( unserialize( $array));

http://php.net/manual/en/book.json.php

방금 당신의 의견을 알아챘습니다.

PHP로

json_encode(unserialize(SerializedVal));

자바스크립트의 경우:

JSON.parse(JsonString);

언급URL : https://stackoverflow.com/questions/14227388/unserialize-php-array-in-javascript

반응형