生成可回调的json格式数据
- ajax回调）传入ajax_cb URL 请求参数，将返回js代码，并在代码中回调以该参数命名的函数；<br />
- iframe回调）传入if_cb URL 请求参数，将返回HTML代码，并在代码中回调以该参数命名的函数； <br />
- 默认）直接返回json数据

@param string $array
@param int $jsonOption = null
483527
public static function jsonCallable($array, $jsonOption = null) {
		$json = json_encode($array, $jsonOption);

		$req = dsp()->getRequest();

		header('Content-Type: text/html; charset=UTF-8');
		
		if (false != ($ifCbUrl = $req->getRequest('if_cb_url'))) {
		    $ifCbUrl = paramDecode($ifCbUrl);
		    if (!preg_match("/^(http|https|ftp):\\/\\//i", $ifCbUrl)) {
		        return '';
		    }
		    		    
		    // 允许回调的限制域名限制
		    $allowDomains = cfg('url.ifCbDomains');
		    if ($allowDomains) {
		        $allowCb = false;
		        $ifCbDomain = str_replace("/.*?:\\/\\/(.*?)\\/.*/", "\\1", $ifCbUrl);
		        foreach ($allowDomains as $allowDomain) {
		            if ($allowDomain[0] == '*') {
		                $allowDomain = ltrim($allowDomain, '*'); // .xxx.xx
		                if (substr($ifCbDomain, -strlen($allowDomain)) == $allowDomain) {
		                    $allowCb = true;
		                    break;
		                }
		            } else if ($ifCbDomain == $allowDomain) {
	                    $allowCb = true;
	                    break;		                
		            }
		        }
		        
		        // 不允许回调的域名，直接显示json
		        if (!$allowCb) {
		            return $json; 
		        }
		    }		    
		    
		    $ifCbUrl .= urlencode($json);
		    
		    // 跳转回调
			$json = "<script type=\"text/javascript\">window.location.href='{$ifCbUrl}'</script>";
		} elseif (false != ($iframeCallback = $req->getRequest('if_cb'))) {
			$callback = preg_replace("/[^0-9a-z_\\.]/i", '', $iframeCallback);
			$callback = preg_replace("/^parent\\./", '', $callback);
			$json = "<script type=\"text/javascript\">try{parent.{$callback}({$json});}catch(e){}</script>";
		} elseif (false != ($ajaxCallback = $req->getRequest('ajax_cb')) && $ajaxCallback != '?') {
			$callback = preg_replace("/[^0-9a-z_\\.]/i", '', $ajaxCallback);
		    $json = "try{{$callback}({$json});}catch(e){}";
		}
		
		return $json;
	}
673690
public function optionsAction($name) {

        $dtProvider = $this->getDataTablesProvider($name);

        $dtWrapper = $this->getDataTablesWrapper($dtProvider);

        $dtOptions = DataTablesWrapperHelper::getOptions($dtWrapper);

        return new JsonResponse($dtOptions);
    }
627926
static public function fromArray($id, array $array=null, callable $callback, array $options=[]){
		$form = static::createInstance($id, $callback);
		$form->parseOptions($options);
		$form->createResource($array);
		$form->render();
	}
1152907
private static function MakeMapperThrowIfJsonDefNotValid(
        string $class,
        array $jsonDef,
        array $array
    ) : Closure {
        $mapper =
            /**
            * @return scalar|array|object|null
            */
            function (string $prop) use ($jsonDef, $array, $class) {
                if (isset($jsonDef[$prop]) && false === is_array($array[$prop])) {
                    static::ThrowBecauseArrayJsonTypeNotValid(
                        $class,
                        $jsonDef[$prop],
                        $prop
                    );
                }

                return $array[$prop];
            };

        return $mapper;
    }
1263129
public function jsonRows()
    {
        $arrWhat = array_values($this->getHeaderColumns());
        $arrWhere = [];
        $arrOrder = ['`id` DESC'];
        $start = 0;
        $pageSize = 15;
        if (isset($_POST['page']) && isset($_POST['pageSize'])) {
            $page = (int) $_POST['page'];
            $pageSize = (int) $_POST['pageSize'];
            $start = $page * $pageSize;
        }
        if (isset($_POST['sort']) && isset($_POST['sortDir'])) {
            $sort = (string) $_POST['sort'];
            $sortDir = (string) $_POST['sortDir'];
            if (!in_array($sortDir, ['ASC', 'DESC'])) {
                throw new Exception('Someone is doing something evil here :(');
            }
            if (!in_array($sort, $this->getAllowedPostColumns())) {
                throw new Exception('Someone is doing something evil here :(');
            }
            $arrOrder = ['`'.$sort.'` '.$sortDir];
        }
        foreach ($arrWhat as $filter) {
            if (in_array($filter, $arrWhat) && isset($_POST['filter_'.$filter])) {
                $arrWhere[$filter] = [
                    "operator" => "like",
                    "value" => '%'.$_POST['filter_'.$filter].'%'
                ];
            }
        }
        
        $arrLimit = [$start, $pageSize];
        $rows = $this->loadByPrepStmt($arrWhat, $arrWhere, $arrOrder, $arrLimit);
        if (count($rows) < 1) {
            return "[]";
        }
        foreach ($rows as $key => $columns) {
            foreach ($columns as $cKey => $column) {
                if ($cKey == "createDate") {
                    $rows[$key][$cKey] = strftime("%d.%m.%Y %H:%M:%S", strtotime($column));
                }
            }
            $rows[$key]['actions'] = $this->renderActionLinks();
        }
        $json = json_encode($rows, JSON_UNESCAPED_UNICODE);
        return $json;
    }
267947
private function writeJson(
        ResponseInterface $response,
        $json,
        int $code = 200
    ): ResponseInterface {
        if ($json instanceof \JsonSerializable) {
            $json = $json->jsonSerialize();
        }

        if (is_array($json) && isset($json['status'])) {
            $code = $json['status'];
        }

        $response->getBody()->write(json_encode($json));

        return $response->withStatus($code)->withHeader(
            'Content-Type',
            'application/json'
        );
    }
505080
public static function create(array $json)
    {
        $setTagsResponse = new SetTagsResponse();
        $setTagsResponse->setStatusCode($json['status_code']);
        $setTagsResponse->setStatusMessage($json['status_message']);

        return $setTagsResponse;
    }
449592
private JSONArray readOptionalArray(JSONObject json, String key) {

        try {
            return json.getJSONArray(key);
        } catch (JSONException e) {
            LOG.debug("Reading optional JSON array failed. Default to provided default value.", e);
        }
        return null;
    }
1323552
public function deserialize($data, BlogOptions $blogOptions = null, array $options = [])
    {
        if (empty($blogOptions)) {
            $blogOptions = new BlogOptions();
        }

        if (!in_array(Options::REFRESH_UUID, $options)) {
            $this->sipe('id', 'setUuid', $data, $blogOptions);
        }

        $this->sipe('authorizeComment', 'setAuthorizeComment', $data, $blogOptions);
        $this->sipe('authorizeAnonymousComment', 'setAuthorizeAnonymousComment', $data, $blogOptions);
        $this->sipe('postPerPage', 'setPostPerPage', $data, $blogOptions);
        $this->sipe('autoPublishPost', 'setAutoPublishPost', $data, $blogOptions);
        $this->sipe('displayTitle', 'setDisplayTitle', $data, $blogOptions);
        $this->sipe('bannerActivate', 'setBannerActivate', $data, $blogOptions);
        $this->sipe('displayPostViewCounter', 'setDisplayPostViewCounter', $data, $blogOptions);
        $this->sipe('tagTopMode', 'setTagTopMode', $data, $blogOptions);
        $this->sipe('maxTag', 'setMaxTag', $data, $blogOptions);
        $this->sipe('displayFullPosts', 'setDisplayFullPosts', $data, $blogOptions);

        if (isset($data['commentModerationMode'])) {
            $blogOptions->setCommentModerationMode($this->getModerationModeIntValue($data['commentModerationMode']));
        }
        if (isset($data['tagCloud'])) {
            $blogOptions->setTagCloud($this->getTagModeIntValue($data['tagCloud']));
        }
        if (isset($data['widgetOrder'])) {
            $blogOptions->setListWidgetBlog($this->deserializeWidgetOrder($data['widgetOrder']));
        }

        return $blogOptions;
    }
141714
protected function responseJson($data, $status = null, $encodingOptions = 0)
    {
        $body = $this->_response->getBody();
        $body->rewind();
        $body->write($json = json_encode($data, $encodingOptions));
        // Ensure that the json encoding passed successfully
        if ($json === false) {
            throw new \RuntimeException(json_last_error_msg(), json_last_error());
        }
        $responseWithJson = $this->_response->withHeader('Content-Type', 'application/json;charset=utf-8');
        if (isset($status)) {
            return $responseWithJson->withStatus($status);
        }
        return $responseWithJson;
    }
1198510
public static function jsonValidate($jsonString, $asArray)
    {
        $json = json_decode($jsonString, $asArray);

        if (json_last_error() != JSON_ERROR_NONE) {
            throw new InvalidJsonException(json_last_error_msg(), json_last_error());
        }

        return $json;
    }
1117875
@Override
	public void compareJSONArray(String prefix, JSONArray expected,
			JSONArray actual, JSONCompareResult result) throws JSONException {
		String arrayPrefix = prefix + "[]";
		if (expected.length() < 1 || expected.length() > 2) {
			result.fail(MessageFormat
					.format("{0}: invalid expectation: expected array should contain either 1 or 2 elements but contains {1} elements",
							arrayPrefix, expected.length()));
			return;
		}
		if (!(expected.get(0) instanceof Number)) {
			result.fail(MessageFormat
					.format("{0}: invalid expectation: {1}expected array size ''{2}'' not a number",
							arrayPrefix, (expected.length() == 1? "": "minimum "), expected.get(0)));
			return;
		}
		if ((expected.length() == 2 && !(expected.get(1) instanceof Number))) {
			result.fail(MessageFormat
					.format("{0}: invalid expectation: maximum expected array size ''{1}'' not a number",
							arrayPrefix, expected.get(1)));
			return;
		}
		int minExpectedLength = expected.getInt(0);
		if (minExpectedLength < 0) {
			result.fail(MessageFormat
					.format("{0}: invalid expectation: minimum expected array size ''{1}'' negative",
							arrayPrefix, minExpectedLength));
			return;
		}
		int maxExpectedLength = expected.length() == 2 ? expected.getInt(1)
				: minExpectedLength;
		if (maxExpectedLength < minExpectedLength) {
			result.fail(MessageFormat
					.format("{0}: invalid expectation: maximum expected array size ''{1}'' less than minimum expected array size ''{2}''",
							arrayPrefix, maxExpectedLength, minExpectedLength));
			return;
		}
		if (actual.length() < minExpectedLength
				|| actual.length() > maxExpectedLength) {
			result.fail(
					arrayPrefix,
					MessageFormat.format(
							"array size of {0}{1} elements",
							minExpectedLength,
							(expected.length() == 2 ? (" to " + maxExpectedLength)
									: "")),
					MessageFormat.format("{0} elements",
							actual.length()));
		}
	}
1141240
public function getListViewJSONString($echo = true) {
        $this->beforeRender();

        if (isset($_POST["start"])) {
            $start = $_POST["start"];
        } else {
            $start = 0;
        }

        if (isset($_POST["length"])) {
            $rowPerPage = $_POST["length"];
        } else {
            $rowPerPage = 25;
        }

        if (isset($_POST["search"]["value"])) {
            $keyword = trim($_POST["search"]["value"]);
        } else {
            $keyword = null;
        }

        if (isset($_POST["order"][0]["column"])) {
           $fieldIndex = $_POST["order"][0]["column"] - 1;

            if ($fieldIndex >= 0) {
                $orderField = $this->getShowFields()[$fieldIndex]->getName();
                $order = $_POST["order"][0]["dir"];
            } else {
                $orderField = null;
                $order = null;
            }


        } else {
            $orderField = null;
            $order = null;
        }

        $list = $this->getListViewData($start, $rowPerPage, $keyword, $orderField, $order);


        $obj = new AjaxResult();

        // Get the total number of record
        $obj->recordsTotal = $this->countTotalListViewData($keyword);
        $obj->recordsFiltered = $obj->recordsTotal;

        if (isset($_POST["draw"])) {
            $obj->draw = $_POST["draw"];
        }

        foreach ($list as $bean) {
            $row = [];

            // Action
            $row[] = $this->getAction($bean);
            $fields = $this->getShowFields();

            foreach ($fields as $field) {
                $row[] = $field->cellValue($bean);
            }

            $obj->data[] = $row;
        }

        $json = json_encode($obj);

        if ($echo) {
            echo $json;
        }

        return $json;
    }
620798
protected function performJsonEncoding($content, array $jsonEncodeOptions = [])
    {
        $jsonEncodeOptions = $this->filterJsonEncodeOptions($jsonEncodeOptions);

        $optionsBitmask = $this->calucateJsonEncodeOptionsBitmask($jsonEncodeOptions);

        if (($encodedString = json_encode($content, $optionsBitmask)) === false) {
            throw new \ErrorException('Error encoding data in JSON format: '.json_last_error());
        }

        return $encodedString;
    }
276811
public function handleJSONRequest( $jsonString ) {
		//Decode JSON string
		$jsonArray = json_decode($jsonString,true);
		if (!$jsonArray) return $this->resp(null,null,-32700,'Cannot Parse JSON');
		if (!isset($jsonArray['jsonrpc'])) return $this->resp(null,null,-32600,'No RPC version');
		if (($jsonArray['jsonrpc']!='2.0')) return $this->resp(null,null,-32600,'Incompatible RPC Version');
		//DO we have an ID to identify this request?
		if (!isset($jsonArray['id'])) return $this->resp(null,null,-32600,'No ID');
		//Fetch the request Identification String.
		$id = $jsonArray['id'];
		//Do we have a method?
		if (!isset($jsonArray['method'])) return $this->resp(null,$id,-32600,'No method');
		//Do we have params?
		if (!isset($jsonArray['params'])) {
			$data = array();
		}
		else {
			$data = $jsonArray['params'];
		}
		//Check method signature
		$method = explode(':',trim($jsonArray['method']));
		if (count($method)!=2) {
			return $this->resp(null, $id, -32600,'Invalid method signature. Use: BEAN:ACTION');
		}
		//Collect Bean and Action
		$beanType = $method[0];
		$action = $method[1];
		//May not contain anything other than ALPHA NUMERIC chars and _
		if (preg_match('/\W/',$beanType)) return $this->resp(null, $id, -32600,'Invalid Bean Type String');
		if (preg_match('/\W/',$action)) return $this->resp(null, $id, -32600,'Invalid Action String');

		try {
			switch($action) {
				case 'store':
					if (!isset($data[0])) return $this->resp(null, $id, -32602,'First param needs to be Bean Object');
					$data = $data[0];
					if (!isset($data['id'])) $bean = RedBean_Facade::dispense($beanType); else
						$bean = RedBean_Facade::load($beanType,$data['id']);
					$bean->import( $data );
					$rid = RedBean_Facade::store($bean);
					return $this->resp($rid, $id);
				case 'load':
					if (!isset($data[0])) return $this->resp(null, $id, -32602,'First param needs to be Bean ID');
					$bean = RedBean_Facade::load($beanType,$data[0]);
					return $this->resp($bean->export(),$id);
				case 'trash':
					if (!isset($data[0])) return $this->resp(null, $id, -32602,'First param needs to be Bean ID');
					$bean = RedBean_Facade::load($beanType,$data[0]);
					RedBean_Facade::trash($bean);
					return $this->resp('OK',$id);
				case 'export':
					if (!isset($data[0])) return $this->resp(null, $id, -32602,'First param needs to be Bean ID');
					$bean = RedBean_Facade::load($beanType,$data[0]);
					$array = RedBean_Facade::exportAll(array($bean),true);
					return $this->resp($array,$id);
				default:
					$modelName = $this->modelHelper->getModelName( $beanType );
					if (!class_exists($modelName)) return $this->resp(null, $id, -32601,'No such bean in the can!');
					$beanModel = new $modelName;
					if (!method_exists($beanModel,$action)) return $this->resp(null, $id, -32601,"Method not found in Bean: $beanType ");
					return $this->resp( call_user_func_array(array($beanModel,$action), $data), $id);
			}
		}
		catch(Exception $exception) {
			return $this->resp(null, $id, -32099,$exception->getCode().'-'.$exception->getMessage());
		}
	}
546833
public static function decode(string $json, int $options = 0)
	{
		if (!\preg_match('##u', $json)) {
			throw new JsonException('Invalid UTF-8 sequence', 5); // workaround for PHP < 5.3.3 & PECL JSON-C
		}

		$forceArray = (bool) ($options & self::FORCE_ARRAY);

		if (!$forceArray && \preg_match('#(?<=[^\\\\]")\\\\u0000(?:[^"\\\\]|\\\\.)*+"\s*+:#', $json)) { // workaround for json_decode fatal error when object key starts with \u0000

			throw new JsonException(static::$messages[\JSON_ERROR_CTRL_CHAR]);
		}

		$args = [$json, $forceArray, 512];

		if (\PHP_VERSION_ID >= 50400 && !(\defined('JSON_C_VERSION') && \PHP_INT_SIZE > 4)) { // not implemented in PECL JSON-C 1.3.2 for 64bit systems
			$args[] = \JSON_BIGINT_AS_STRING;
		}

		$value = \json_decode(...$args);

		if ($value === null && $json !== '' && \strcasecmp($json, 'null')) { // '' is not clearing json_last_error
			$error = \json_last_error();

			throw new JsonException(static::$messages[$error] ?? 'Unknown error', $error);
		}

		return $value;
	}
1275242
public function encode($data, $options = 0) {
        $json = null;

        if ($data instanceof IArrayable) {
            $json = @json_encode($data->toArray(), $options);
        } else if ($data instanceof IJsonable) {
            $json = $data->toJson($options);
        } else if (is_array($data) || is_object($data)) {
            $json =  @json_encode($data, $options);
        } else {
            throw new InvalidDataTypeException(
                s('Can not convert data of type "%s" to json.', get_type($data))
            );
        }

        if ($json === false) {
            throw new JsonEncodeException(json_last_error_msg(), $data);
        }

        return $json;
    }