<?php
class JSObject implements ArrayAccess {
function __construct($d) {
$this->data = array_replace($this->data, $d);
}
public function __set($name, $value) {
$this->data[$name] = $value;
}
public function __get($name) {
global $undefined;
return $this->data[$name];
} else {
return $undefined;
}
}
public function __isset($name) {
}
public function __unset($name) {
unset($this->data[$name]); }
}
public function offsetExists($item) {
return $this->__isset($item);
}
public function offsetGet($item) {
return $this->__get($item);
}
public function offsetSet($item, $value) {
$this->__set($item, $value);
}
public function offsetUnset($item) {
$this->__unset($item);
}
function __toString() {
return '[object Object]';
}
public function __debugInfo() {
return $this->data;
}
}
class JSUndefined implements ArrayAccess {
public function __set($name, $value) {
global $undefined;
return $undefined;
}
public function __get($name) {
global $undefined;
return $undefined;
}
public function __isset($name) {
global $undefined;
return $undefined;
}
public function __unset($name) {
global $undefined;
return $undefined;
}
public function offsetExists($item) {
global $undefined;
return $undefined;
}
public function offsetGet($item) {
global $undefined;
return $undefined;
}
public function offsetSet($item, $value) {
global $undefined;
return $undefined;
}
public function offsetUnset($item) {
global $undefined;
return $undefined;
}
function __toString() {
return 'undefined';
}
}
$undefined = new JSUndefined();
$x = new JSObject(['a' => 12]);
echo sprintf("(%s, %s)\n", $x->a, $x['a']);
$x->a = 42;
echo sprintf("(%s, %s)\n", $x->a, $x['a']);
$x['b'] = 43;
echo sprintf("(%s, %s)\n", $x->b, $x['b']);
PD9waHAKCmNsYXNzIEpTT2JqZWN0IGltcGxlbWVudHMgQXJyYXlBY2Nlc3MgewogICAgcHJpdmF0ZSAkZGF0YSA9IGFycmF5KCk7CgogICAgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGQpIHsKICAgICAgICAkdGhpcy0+ZGF0YSA9IGFycmF5X3JlcGxhY2UoJHRoaXMtPmRhdGEsICRkKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gX19zZXQoJG5hbWUsICR2YWx1ZSkgewogICAgICAgICR0aGlzLT5kYXRhWyRuYW1lXSA9ICR2YWx1ZTsKICAgIH0KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2dldCgkbmFtZSkgewogICAgICAgIGdsb2JhbCAkdW5kZWZpbmVkOwogICAgICAgIGlmKGFycmF5X2tleV9leGlzdHMoJG5hbWUsICR0aGlzLT5kYXRhKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmRhdGFbJG5hbWVdOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAkdW5kZWZpbmVkOwogICAgICAgIH0KICAgIH0KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2lzc2V0KCRuYW1lKSB7CiAgICAgICAgcmV0dXJuIGFycmF5X2tleV9leGlzdHMoJG5hbWUsICR0aGlzLT5kYXRhKTsKICAgIH0KICAgIHB1YmxpYyBmdW5jdGlvbiBfX3Vuc2V0KCRuYW1lKSB7CiAgICAgICAgaWYoYXJyYXlfa2V5X2V4aXN0cygkbmFtZSwgJHRoaXMtPmRhdGEpKSB7CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5kYXRhWyRuYW1lXSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBvZmZzZXRFeGlzdHMoJGl0ZW0pIHsKICAgICAgICByZXR1cm4gJHRoaXMtPl9faXNzZXQoJGl0ZW0pOwogICAgfQogICAgcHVibGljIGZ1bmN0aW9uIG9mZnNldEdldCgkaXRlbSkgewogICAgICAgIHJldHVybiAkdGhpcy0+X19nZXQoJGl0ZW0pOwogICAgfQogICAgcHVibGljIGZ1bmN0aW9uIG9mZnNldFNldCgkaXRlbSwgJHZhbHVlKSB7CiAgICAgICAgJHRoaXMtPl9fc2V0KCRpdGVtLCAkdmFsdWUpOwogICAgfQogICAgcHVibGljIGZ1bmN0aW9uIG9mZnNldFVuc2V0KCRpdGVtKSB7CiAgICAgICAgJHRoaXMtPl9fdW5zZXQoJGl0ZW0pOwogICAgfQogICAgICAgCiAgICBmdW5jdGlvbiBfX3RvU3RyaW5nKCkgewogICAgICAgIHJldHVybiAnW29iamVjdCBPYmplY3RdJzsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gX19kZWJ1Z0luZm8oKSB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5kYXRhOwogICAgfQp9ICAgICAgICAKCmNsYXNzIEpTVW5kZWZpbmVkIGltcGxlbWVudHMgQXJyYXlBY2Nlc3MgewogICAgcHVibGljIGZ1bmN0aW9uIF9fc2V0KCRuYW1lLCAkdmFsdWUpIHsKICAgICAgICBnbG9iYWwgJHVuZGVmaW5lZDsKICAgICAgICByZXR1cm4gJHVuZGVmaW5lZDsKICAgIH0KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2dldCgkbmFtZSkgewogICAgICAgIGdsb2JhbCAkdW5kZWZpbmVkOwogICAgICAgIHJldHVybiAkdW5kZWZpbmVkOwogICAgfQogICAgcHVibGljIGZ1bmN0aW9uIF9faXNzZXQoJG5hbWUpIHsKICAgICAgICBnbG9iYWwgJHVuZGVmaW5lZDsKICAgICAgICByZXR1cm4gJHVuZGVmaW5lZDsKICAgIH0KICAgIHB1YmxpYyBmdW5jdGlvbiBfX3Vuc2V0KCRuYW1lKSB7CiAgICAgICAgZ2xvYmFsICR1bmRlZmluZWQ7CiAgICAgICAgcmV0dXJuICR1bmRlZmluZWQ7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIG9mZnNldEV4aXN0cygkaXRlbSkgewogICAgICAgIGdsb2JhbCAkdW5kZWZpbmVkOwogICAgICAgIHJldHVybiAkdW5kZWZpbmVkOwogICAgfQogICAgcHVibGljIGZ1bmN0aW9uIG9mZnNldEdldCgkaXRlbSkgewogICAgICAgIGdsb2JhbCAkdW5kZWZpbmVkOwogICAgICAgIHJldHVybiAkdW5kZWZpbmVkOwogICAgfQogICAgcHVibGljIGZ1bmN0aW9uIG9mZnNldFNldCgkaXRlbSwgJHZhbHVlKSB7CiAgICAgICAgZ2xvYmFsICR1bmRlZmluZWQ7CiAgICAgICAgcmV0dXJuICR1bmRlZmluZWQ7CiAgICB9CiAgICBwdWJsaWMgZnVuY3Rpb24gb2Zmc2V0VW5zZXQoJGl0ZW0pIHsKICAgICAgICBnbG9iYWwgJHVuZGVmaW5lZDsKICAgICAgICByZXR1cm4gJHVuZGVmaW5lZDsKICAgIH0KCiAgICBmdW5jdGlvbiBfX3RvU3RyaW5nKCkgewogICAgICAgIHJldHVybiAndW5kZWZpbmVkJzsKICAgIH0KfQoKJHVuZGVmaW5lZCA9IG5ldyBKU1VuZGVmaW5lZCgpOwoKCiR4ID0gbmV3IEpTT2JqZWN0KFsnYScgPT4gMTJdKTsKZWNobyBzcHJpbnRmKCIlcyB8ICVzXG4iLCAkeCwgcHJpbnRfcigkeCwgdHJ1ZSkpOwoKZWNobyBzcHJpbnRmKCIoJXMsICVzKVxuIiwgJHgtPmEsICR4WydhJ10pOwoKJHgtPmEgPSA0MjsKCmVjaG8gc3ByaW50ZigiKCVzLCAlcylcbiIsICR4LT5hLCAkeFsnYSddKTsKCiR4WydiJ10gPSA0MzsKCmVjaG8gc3ByaW50ZigiKCVzLCAlcylcbiIsICR4LT5iLCAkeFsnYiddKTsKCnVuc2V0KCR4LT5iKTsKCmVjaG8gc3ByaW50ZigiJXNcbiIsICR4LT5iKTsKCmVjaG8gc3ByaW50ZigiJXNcbiIsIHZhcl9leHBvcnQoJHgtPmIgPT0gJHVuZGVmaW5lZCwgdHJ1ZSkpOwoKZWNobyBzcHJpbnRmKCIlc1xuIiwgcHJpbnRfcigkeCwgdHJ1ZSkpOwo=