Current section
Files
Jump to
Current section
Files
lib/phex.ex
defmodule Phex do
@moduledoc ~s"""
A PHP serialized decoder and encoder.
## Installation
The package can be installed by adding `phex` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:phex, "~> #{Mix.Project.config()[:version]}"}
]
end
```
## Basic Usage
iex> Phex.encode!(%{"age" => 42, "name" => "John Doe"})
"a:2:{s:3:\\\"age\\\";i:42;s:4:\\\"name\\\";s:8:\\\"John Doe\\\";}"
iex> Phex.decode!("a:2:{s:3:\\\"age\\\";i:42;s:4:\\\"name\\\";s:8:\\\"John Doe\\\";}")
%{"age" => 42, "name" => "John Doe"}
## PHP Serialization
Currently only maps with keys which are either integers or strings are supported.
This works in most cases but can create invalid serialized data if the peculiarities of PHP arrays are not taken into account.
More information can be found in the PHP manual [here](https://www.php.net/manual/en/language.types.array.php).
As of now supported types are ...
iex> encode!(nil)
"N;"
iex> decode!("N;")
nil
### Boolean
iex> encode!(true)
"b:1;"
iex> decode!("b:0;")
false
### Integer
iex> encode!(9000)
"i:9000;"
iex> decode!("i:-212;")
-212
### Float
iex> encode!(3.14159265359)
"d:3.14159265359;"
iex> decode!("d:6.62607004;")
6.62607004
### String
iex> encode!("Hello")
"s:5:\\\"Hello\\\";"
iex> decode!("s:5:\\\"World\\\";")
"World"
### Maps (PHP-Arrays)
iex> encode!(%{"Blue" => 2, "Pink" => 4})
"a:2:{s:4:\\\"Blue\\\";i:2;s:4:\\\"Pink\\\";i:4;}"
iex> decode!("a:2:{s:6:\\\"Bunker\\\";s:4:\\\"Blue\\\";s:7:\\\"Buscemi\\\";s:4:\\\"Pink\\\";}")
%{"Bunker" => "Blue", "Buscemi" => "Pink"}
iex> decode!("a:2:{s:6:\\\"Bunker\\\";s:4:\\\"Blue\\\";s:7:\\\"Buscemi\\\";s:4:\\\"Pink\\\";}", arrays: :strict)
[{"Bunker", "Blue"}, {"Buscemi", "Pink"}]
"""
alias Phex.Encode
@type key :: String.t() | integer()
@type t :: nil | boolean() | number() | String.t() | array()
@type array :: [{key, t()}]
@type decode_opts :: [{:arrays, :naive | :strict} | decode_opts()]
# @type encode_opts :: [{:arrays, :naive | :strict} | encode_opts()]
defmodule EncodeError do
defexception [:message]
end
defmodule DecodeError do
defexception [:message]
end
def encode!(term) do
term
|> Encode.encode()
|> IO.iodata_to_binary()
end
def encode(term) do
{:ok, encode!(term)}
rescue
e in Phex.EncodeError -> {:error, e.message}
end
def decode!(binary, opt \\ :naive) when is_binary(binary) do
case decode(binary, opt) do
{:ok, result, _rest} -> result
{:error, reason, _rest} -> raise DecodeError, message: reason
end
end
# @spec decode(binary(), decode_opts()) ::
# {:ok, t(), binary()} | {:error, reason :: String.t(), binary()}
def decode(binary, opt \\ :naive) do
# dec_opts = Enum.into(opts, %{arrays: :naive})
Phex.Decode.decode(binary, opt)
end
end