Pragmatism in the real world

Validating JSON with ZF2's Zend\Validator

Let’s say that you have an admin form where the user can enter JSON and you’d like to validate that the JSON parses before allowing the user to submit. To do this, you can use the rather excellent jsonlint project by Jordi Boggiano. Obviously, add it via Compser :)

Usage is simple:

use Seld\JsonLint\JsonParser;
use Seld\JsonLint\ParsingException;

$parser = new JsonParser();

$result = $parser->lint($json);
if ($result instanceof ParsingException) {
    // $json is invalid JSON
}

We can wrap this up into a Zend Framework 2 validator quite easily:

<?php

namespace RKA\Validator;

use Zend\Validator\AbstractValidator;
use Seld\JsonLint\JsonParser;
use Seld\JsonLint\ParsingException;


class Json extends AbstractValidator
{
    const INVALID      = 'jsonInvalid';

    /**
     * Json parser
     *
     * @var \Seld\JsonLint\JsonParser
     */
    protected static $parser = null;

    /**
     * Validation failure message template definitions
     *
     * @var array
     */
    protected $messageTemplates = array(
        self::INVALID      => "Json is invalid: '%reason%'",
    );

    /**
     * Additional variables available for validation failure messages
     *
     * @var array
     */
    protected $messageVariables = array(
        'reason' => 'reason',
    );

    /**
     * @var string
     */
    protected $reason;

    /**
     * Returns true if and only if $value is valid JSON
     *
     * @param  string $value
     * @return bool
     */
    public function isValid($value)
    {
        $parser = new JsonParser();

        $result = $parser->lint($value);

        if ($result instanceof ParsingException) {
            $this->reason = $result->getMessage();
            $this->error(self::INVALID);
            return false;
        }

        return true;
    }
}

Simply add RKA\Validator\Json to the input filter of the element in question and we’re done.

One thought on “Validating JSON with ZF2's Zend\Validator

Comments are closed.