- _handleJsonError misses @throws
- tests: testDecodeFromPython assert parameters are in the wrong order
- use exception codes so exceptions can be distinguished programmatically
- I'm not fully happy with the "all static methods" approach, even if it may be fine here. Smells a bit. Does it make sense to have an JWT object and pre-set the key, so that I can encode/decode multiple tokens?
- use static:: instead of JWT::
- the tests don't really test the encoding/decoding functionality except the python test. All others just work by $str = decode(encode($str)) - so I could replace the implementation with anything, and it would work
- why are all (except one) methods public?
- why is the one method private and not protected?