balping/json-raw-encoder
Laravel helper for encoding JSON while preserving “raw” fragments (like JS functions or pre-encoded JSON) without extra quoting/escaping. Handy for configs and API payloads when parts must stay untouched, with a simple API and reliable output.
Installation
composer require balping/json-raw-encoder
Add to composer.json if not auto-loaded:
"autoload": {
"psr-4": {
"App\\": "app/",
"Balping\\JsonRawEncoder\\": "vendor/balping/json-raw-encoder/src/"
}
}
Run composer dump-autoload.
First Use Case Encode an array containing raw JavaScript objects (e.g., callbacks, functions) without JSON serialization errors:
use Balping\JsonRawEncoder\JsonRawEncoder;
$data = [
'name' => 'John',
'callback' => 'function() { console.log("Hello!"); }'
];
$encoder = new JsonRawEncoder();
$json = $encoder->encode($data);
// Output: {"name":"John","callback":function() { console.log("Hello!"); }}
Where to Look First
JsonRawEncoder (handles encoding logic).Replace Laravel’s default JSON encoder (e.g., in API responses, Blade views, or AJAX handlers):
// In a controller or service
return response()->json($encoder->encode($yourDataWithRawJS));
Override the default JSON response macro:
use Balping\JsonRawEncoder\JsonRawEncoder;
$encoder = new JsonRawEncoder();
Response::macro('jsonRaw', function ($data, $status = 200, array $headers = [], $options = 0) use ($encoder) {
return $this->json($encoder->encode($data), $status, $headers, $options);
});
Usage:
return response()->jsonRaw(['callback' => 'alert("Hi!");']);
Create a custom Blade directive for JSON encoding:
// In AppServiceProvider@boot()
Blade::directive('jsonraw', function ($expression) {
return "<?php echo (new \\Balping\\JsonRawEncoder\\JsonRawEncoder())->encode({$expression}); ?>";
});
Usage in Blade:
<script>
const data = @jsonraw($yourArrayWithRawJS);
</script>
json_encode for invalid inputs:
try {
return $encoder->encode($data);
} catch (\Exception $e) {
return json_encode($data); // Fallback
}
Security Risks
$safeJs = htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
$data['callback'] = $safeJs;
Browser Compatibility
Circular References
json_encode with JSON_THROW_ON_ERROR or a library like spatie/array-to-object for complex objects.False Positives
'function() { return "text"; }') will be encoded literally. Only use this for actual raw JS.Validate Input Check if the input is a string that could be JS before encoding:
if (is_string($data['callback']) && stripos($data['callback'], 'function') !== false) {
$json = $encoder->encode($data);
} else {
$json = json_encode($data);
}
Log Encoded Output Log the final JSON string to verify raw JS is preserved:
\Log::debug('Encoded JSON:', [$encoder->encode($data)]);
Extension Points
JsonRawEncoder to add preprocessing:
class CustomEncoder extends JsonRawEncoder {
protected function encodeValue($value) {
if (is_string($value) && $this->isValidJs($value)) {
return $value; // Preserve raw JS
}
return parent::encodeValue($value);
}
private function isValidJs(string $str): bool {
// Add validation logic (e.g., check for balanced parentheses).
return true;
}
}
Configuration Quirks
$encoder = new JsonRawEncoder(new JsValidator());
Performance
json_encode + manual string replacement (e.g., str_replace for known JS patterns). This package may add overhead for simple cases.How can I help you explore Laravel packages today?