Initial commit: apps.supersam24.ru
This commit is contained in:
commit
e955e1da36
6566 files changed
+1271095
No files matched your search
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
; This file is for unifying the coding style for different editors and IDEs.
|
||||
; More information at http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
Vendored
+46
@@ -0,0 +1,46 @@
|
||||
# Changelog
|
||||
|
||||
All Notable changes to `Env` will be documented in this file
|
||||
|
||||
## 2.1.0 - 2016-10-06
|
||||
### Fixed
|
||||
- Single quote variables in single quotes will be treated as strings
|
||||
|
||||
## 2.0.0 - 2016-01-07
|
||||
### Altered
|
||||
- Must pass `file_get_contents()` or content string to `parser` not a `file`
|
||||
- Keys must not start with a number
|
||||
- Make `#` in unquoted into string if no space, e.g. `value#notacomment`
|
||||
|
||||
### Removed
|
||||
- File logic (Env.php)
|
||||
|
||||
## 1.1.0 - 2016-01-05
|
||||
### Added
|
||||
- Support for parameter expansions: [default value](http://wiki.bash-hackers.org/syntax/pe#use_a_default_value) and [assign default value](http://wiki.bash-hackers.org/syntax/pe#assign_a_default_value)
|
||||
- Support for php `5.3` and `hhvm`
|
||||
|
||||
### Altered
|
||||
- Updated README
|
||||
- Test cases
|
||||
|
||||
## 1.0.2 - 2016-01-03
|
||||
### Altered
|
||||
- Updated README
|
||||
|
||||
## 1.0.1 - 2015-12-21
|
||||
### Fixed
|
||||
- Fixed composer.json
|
||||
|
||||
## 1.0.0 - 2015-12-13
|
||||
### Altered
|
||||
- Bump to version 1
|
||||
- Refactored
|
||||
|
||||
## 0.2.0 - 2015-12-13
|
||||
### Altered
|
||||
- General refactoring and clean up for 0.2.0
|
||||
|
||||
## 0.1.0 - 2015-12-13
|
||||
### Added
|
||||
- Initial Release
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
# Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing other's private information, such as physical or electronic addresses, without explicit permission
|
||||
* Other unethical or unprofessional conduct.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
|
||||
|
||||
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community in a direct capacity. Personal views, beliefs and values of individuals do not necessarily reflect those of the organisation or affiliated individuals and organisations.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
|
||||
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
# Contributing
|
||||
|
||||
Contributions are **welcome** and will be fully **credited**.
|
||||
|
||||
We accept contributions via Pull Requests on [Github](https://github.com/m1/env).
|
||||
|
||||
|
||||
## Pull Requests
|
||||
|
||||
- **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - Check the code style with ``$ composer check-codestyle`` and fix it with ``$ composer fix-codestyle``.
|
||||
|
||||
- **Add tests!** - Your patch won't be accepted if it doesn't have tests.
|
||||
|
||||
- **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date.
|
||||
|
||||
- **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option.
|
||||
|
||||
- **Create feature branches** - Don't ask us to pull from your master branch.
|
||||
|
||||
- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
|
||||
|
||||
- **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting.
|
||||
|
||||
|
||||
## Running Tests
|
||||
|
||||
``` bash
|
||||
$ composer test
|
||||
```
|
||||
|
||||
|
||||
**Happy coding**!
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
# The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Miles Croxford <hello@milescroxford.com>
|
||||
|
||||
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
> of this software and associated documentation files (the "Software"), to deal
|
||||
> in the Software without restriction, including without limitation the rights
|
||||
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
> copies of the Software, and to permit persons to whom the Software is
|
||||
> furnished to do so, subject to the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be included in
|
||||
> all copies or substantial portions of the Software.
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
> THE SOFTWARE.
|
||||
Vendored
+612
@@ -0,0 +1,612 @@
|
||||
# Env
|
||||
|
||||
[](https://twitter.com/milescroxford)
|
||||
[![Latest Version on Packagist][ico-version]][link-packagist]
|
||||
[![Software License][ico-license]](LICENSE.md)
|
||||
[![Build Status][ico-travis]][link-travis]
|
||||
[![Coverage Status][ico-scrutinizer]][link-scrutinizer]
|
||||
[![Quality Score][ico-code-quality]][link-code-quality]
|
||||
[![Downloads][ico-downloads]][link-downloads]
|
||||
[](https://styleci.io/repos/47935133)
|
||||
|
||||
[![Sensio badge][ico-sensio]][link-sensio]
|
||||
|
||||
Env is a lightweight library bringing .env file parser compatibility to PHP. In short - it enables you to read .env files with PHP.
|
||||
|
||||
* [Why?](#why)
|
||||
* [Requirements](#requirements)
|
||||
* [Install](#install)
|
||||
* [Usage](#usage)
|
||||
* [Basic](#basic)
|
||||
* [Context variables](#context)
|
||||
* [Syntax](#syntax)
|
||||
* [Assignment](#assignment)
|
||||
* [Strings](#strings)
|
||||
* [Numbers](#numbers)
|
||||
* [Booleans](#booleans)
|
||||
* [Null](#null)
|
||||
* [Variables](#variables)
|
||||
* [Default Value/Assignment](#parameter-expansion)
|
||||
* [Comments](#comments)
|
||||
* [.env example](#env-example)
|
||||
* [Notes](#notes)
|
||||
* [Source](#source)
|
||||
* [Other library comparisons](#other-library-comparisons)
|
||||
* [Todo](#todo)
|
||||
* [Change log](#change-log)
|
||||
* [Testing](#testing)
|
||||
* [Contributing](#Contributing)
|
||||
* [Security](#security)
|
||||
* [Credits](#credits)
|
||||
* [License](#license)
|
||||
|
||||
|
||||
## Why?
|
||||
Env aims to bring a unified parser for env together for PHP rather than having a few incomplete or buggy parsers written
|
||||
into other libraries. This library is not meant as a complete package for config loading like other libraries as this
|
||||
is out of scope for this library. If you need something like that check out [Vars](http://github.com/m1/Vars) which incorporates
|
||||
this library so you can load Env and other file types if you want, or checkout [PHP Dotenv](https://github.com/josegonzalez/php-dotenv)
|
||||
if you only need .env parsing
|
||||
|
||||
## Requirements
|
||||
|
||||
Env requires PHP version `5.3+` - supported and tested on `5.3`, `5.4`, `5.5`, `5.6`, `7` and `hhvm`.
|
||||
|
||||
## Install
|
||||
|
||||
Via Composer
|
||||
|
||||
``` bash
|
||||
$ composer require m1/env
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic
|
||||
|
||||
test.env
|
||||
```bash
|
||||
TEST_1 = VALUE
|
||||
```
|
||||
|
||||
example.php
|
||||
```php
|
||||
<?php
|
||||
|
||||
//both examples return the same thing
|
||||
|
||||
// example 1 -- standard
|
||||
use M1\Env\Parser;
|
||||
|
||||
$env = new Parser(file_get_contents('test.env'));
|
||||
$arr = $env->getContent();
|
||||
|
||||
// example 2 -- statically
|
||||
$arr = Parser::parse(file_get_contents('test.env'));
|
||||
|
||||
var_dump($arr);
|
||||
// [
|
||||
// "TEST_1" => "VALUE"
|
||||
// ]
|
||||
```
|
||||
### Context variables
|
||||
|
||||
test_context.env
|
||||
```bash
|
||||
TEST_1 = $EXTERNAL
|
||||
TEST_2 = VALUE
|
||||
```
|
||||
|
||||
example_context.php
|
||||
```php
|
||||
<?php
|
||||
|
||||
//both examples return the same thing
|
||||
|
||||
// example 1 -- standard
|
||||
use M1\Env\Parser;
|
||||
|
||||
$env = new Parser(file_get_contents('test_context.env'), array('EXTERNAL' => 'external'));
|
||||
$arr = $env->getContent();
|
||||
|
||||
// example 2 -- statically
|
||||
$arr = Parser::parse(file_get_contents('test_context.env'), array('EXTERNAL' => 'external'));
|
||||
|
||||
var_dump($arr);
|
||||
// [
|
||||
// "TEST_1" => "external"
|
||||
// "TEST_2" => "VALUE"
|
||||
// ]
|
||||
```
|
||||
|
||||
### Syntax
|
||||
|
||||
The Syntax is slightly more relaxed than bash, but still remains quite bash like
|
||||
|
||||
#### Assignment
|
||||
To assign values the syntax is `key = value`, unlike bash the assignment is pretty relaxed, any of the below are valid:
|
||||
```bash
|
||||
TEST1 = value
|
||||
TEST2= VALUE
|
||||
TEST3 =VALUE
|
||||
TEST4=VALUE
|
||||
TEST5 = VALUE
|
||||
TEST6 = VALUE
|
||||
```
|
||||
|
||||
However keys can not start with a number, e.g.:
|
||||
|
||||
```bash
|
||||
1notvalid = nope
|
||||
```
|
||||
|
||||
Will throw a `ParseException`
|
||||
|
||||
You can also add `export` to the start of variables to `source` the file in bash ([see here](#source) for more info):
|
||||
|
||||
```bash
|
||||
export TEST1=value
|
||||
```
|
||||
|
||||
#### Strings
|
||||
|
||||
Strings can either be in quotes (single or double) or without:
|
||||
|
||||
```bash
|
||||
TEST1 = value
|
||||
TEST2 = "value"
|
||||
TEST3 = 'value'
|
||||
```
|
||||
|
||||
To escape new lines or quotes is the standard backslash:
|
||||
|
||||
```bash
|
||||
TEST1 = "value \n value"
|
||||
TEST2 = "value \"value\" value"
|
||||
TEST3 = 'value \' value \' value'
|
||||
```
|
||||
|
||||
If you feature two quoted strings as a value then only the first quoted string will be assigned to the key:
|
||||
|
||||
```bash
|
||||
TEST1 = "value value" "this sentence in quotes will not be counted"
|
||||
```
|
||||
|
||||
#### Numbers
|
||||
|
||||
Numbers are fairly standard:
|
||||
```bash
|
||||
TEST1 = 1
|
||||
TEST2 = 2
|
||||
```
|
||||
|
||||
Decimal numbers will be automatically cast to floats:
|
||||
```bash
|
||||
TEST1 = 1.1 # `float` type
|
||||
TEST2 = 2 # `int` type
|
||||
```
|
||||
|
||||
If you quote numbers they will be counted as strings, or if you have two numbers on one line:
|
||||
```bash
|
||||
TEST1 = 33 33 # `string` type
|
||||
TEST2 = "22" # `string` type
|
||||
```
|
||||
|
||||
#### Booleans
|
||||
|
||||
Booleans can be `true`, `false`, `yes` and `no`:
|
||||
```bash
|
||||
TEST1 = true
|
||||
TEST2 = false
|
||||
TEST3 = yes
|
||||
TEST4 = no
|
||||
```
|
||||
|
||||
Booleans are case-insensitive:
|
||||
```bash
|
||||
TEST1 = True
|
||||
TEST2 = False
|
||||
TEST3 = YES
|
||||
TEST4 = NO
|
||||
```
|
||||
|
||||
Booleans in quotes will be treated as strings:
|
||||
```bash
|
||||
TEST1 = "true" # `string` type
|
||||
TEST2 = "YES" # `string` type
|
||||
TEST3 = 'NO' # `string` type
|
||||
```
|
||||
|
||||
#### Null
|
||||
|
||||
Both of the below are counted as null values:
|
||||
```bash
|
||||
TEST1 =
|
||||
TEST2 = null
|
||||
```
|
||||
|
||||
Whereas an empty string is counted as a string:
|
||||
```bash
|
||||
TEST1 = "" # `string` type
|
||||
TEST2 = '' # `string` type
|
||||
```
|
||||
|
||||
#### Variables
|
||||
|
||||
Variables are based of the bash syntax:
|
||||
```bash
|
||||
TEST1 = 'hello'
|
||||
TEST2 = ${TEST27} # 'hello'
|
||||
```
|
||||
|
||||
The types of variable get passed to the calling variable if there is only one variable. If there are more than one variable,
|
||||
the calling variable is automatically cast to a string:
|
||||
```bash
|
||||
TEST1 = 1 # `int` type
|
||||
TEST2 = 2 # `int` type
|
||||
TEST3 = ${TEST1} ${TEST2} # `string` type
|
||||
TEST4 = true # `bool` type
|
||||
TEST5 = ${TEST4} # `bool` type
|
||||
```
|
||||
|
||||
Also if the variable is in quotes then the variable will be automatically cast as a string:
|
||||
```bash
|
||||
TEST1 = 1 # `int` type
|
||||
TEST2 = "${TEST1}" # `string` type
|
||||
```
|
||||
|
||||
But you can use variables without quotes and they'll be cast as strings:
|
||||
```bash
|
||||
TEST1 = foo
|
||||
TEST2 = bar
|
||||
TEST3 = ${TEST1}/${TEST2} # `string` type
|
||||
```
|
||||
|
||||
Variables are useful to use in strings like so:
|
||||
```bash
|
||||
TEST1 = "foo"
|
||||
TEST2 = 'bar'
|
||||
TEST3 = "hello ${TEST1} and ${TEST2}"
|
||||
```
|
||||
|
||||
Null values are passed and casted as empty strings if in quotes:
|
||||
```bash
|
||||
TEST1 = null
|
||||
TEST2 = ${TEST1} # `null` type
|
||||
TEST3 = "${TEST1}" # `string` type
|
||||
```
|
||||
|
||||
Single Quotes with variables will be counted as strings:
|
||||
```bash
|
||||
TEST1 = '${hello} # `string` type, will output: '${hello}'
|
||||
```
|
||||
|
||||
|
||||
##### Parameter Expansion
|
||||
|
||||
You can do parameter expansion, so far you can only do [default values](http://wiki.bash-hackers.org/syntax/pe#use_a_default_value)
|
||||
and [assign default values](http://wiki.bash-hackers.org/syntax/pe#assign_a_default_value) like in the bash syntax:
|
||||
|
||||
```bash
|
||||
TEST1 = foo
|
||||
TEST2 = ${TEST3:=bar}
|
||||
TEST4 = ${TEST5=bar}
|
||||
TEST6 = ${TEST7:-bar}
|
||||
TEST8 = ${TEST9-bar}
|
||||
```
|
||||
|
||||
The default value parameter expansion syntax is `:-`, the explanation on the [bash-hackers wiki](http://wiki.bash-hackers.org/syntax/pe#use_a_default_value) for this is:
|
||||
> SYNTAX:
|
||||
>
|
||||
>`${PARAMETER:-WORD}`
|
||||
>
|
||||
>`${PARAMETER-WORD}`
|
||||
>
|
||||
>If the parameter PARAMETER is unset (never was defined) or null (empty), this one expands to WORD, otherwise it
|
||||
>expands to the value of PARAMETER, as if it just was ${PARAMETER}. If you omit the : (colon), like shown in the second
|
||||
>form, the default value is only used when the parameter was unset, not when it was empty.
|
||||
|
||||
For example:
|
||||
```bash
|
||||
TEST1 = foo
|
||||
TEST2 = ${TEST1:-bar} # TEST1 is set so the value of TEST2 = foo
|
||||
|
||||
TEST3 = ${TEST4:-bar} # TEST4 is not set so the value of TEST3 = bar
|
||||
|
||||
TEST5 = null
|
||||
TEST6 = ${TEST5-bar} # TEST5 is set but empty so the value of TEST6 = null
|
||||
TEST7 = ${TEST6:-bar} # TEST5 is set and empty so the value of TEST7 = bar
|
||||
|
||||
```
|
||||
|
||||
The assign default value parameter expansion is `:=`, the explanation on the [bash-hackers wiki](http://wiki.bash-hackers.org/syntax/pe#assign_a_default_value) for this is:
|
||||
> SYNTAX:
|
||||
>
|
||||
>`${PARAMETER:=WORD}`
|
||||
>
|
||||
>`${PARAMETER=WORD}`
|
||||
>
|
||||
>This one works like the using default values, but the default text you give is not only expanded, but also assigned
|
||||
>to the parameter, if it was unset or null. Equivalent to using a default value, when you omit the : (colon), as
|
||||
>shown in the second form, the default value will only be assigned when the parameter was unset.
|
||||
|
||||
For example:
|
||||
```bash
|
||||
TEST1 = foo
|
||||
TEST2 = ${TEST1:=bar} # TEST1 is set so the value of TEST2 = foo
|
||||
|
||||
TEST3 = ${TEST4:=bar} # TEST4 is not set so the value of TEST3 = bar and TEST4 = bar
|
||||
|
||||
TEST5 = null
|
||||
TEST6 = ${TEST5=bar} # TEST5 is set but emtpy so the value of TEST6 = null
|
||||
TEST7 = ${TEST6=bar} # TEST5 is set and empty so the value of TEST7 = bar and TEST5 = bar
|
||||
```
|
||||
#### Comments
|
||||
|
||||
To comment, just use the `#` syntax, you can also comment inline like so:
|
||||
```bash
|
||||
# This is a comment
|
||||
TEST1 = bar # and so is this
|
||||
```
|
||||
|
||||
If you put a `#` without a space in a unquoted string, it will be parsed as a string:
|
||||
|
||||
```bash
|
||||
TEST1 = hello#notacomment
|
||||
```
|
||||
|
||||
### .env example
|
||||
|
||||
```bash
|
||||
# Comments are done like this
|
||||
|
||||
# Standard key=value
|
||||
TEST1 = value
|
||||
TEST2 = value
|
||||
TEST3 = value # You can also comment inline like this
|
||||
|
||||
# Strings
|
||||
TEST4 = "value"
|
||||
|
||||
## The value of the below variable will be TK4 = "value value"
|
||||
TEST5 = "value value" "this sentence in quotes will not be counted"
|
||||
|
||||
## Escape newline
|
||||
TEST6 = "value \n value"
|
||||
|
||||
## Escape double quotes
|
||||
TEST7 = "value \"value\" value"
|
||||
|
||||
## You can also exchange any of the above for single quotes, eg:
|
||||
TEST8 = 'value'
|
||||
TEST9 = 'value \' value \' value'
|
||||
|
||||
# Numbers
|
||||
TEST10 = 1
|
||||
TEST11 = 1.1
|
||||
TEST12 = 33 33 # Will output as a `string` -- not a number as two numbers are given
|
||||
TEST13 = "33" # 33 -- `string` type
|
||||
|
||||
# Bools -- All of the below are valid booleans
|
||||
TEST14 = true
|
||||
TEST15 = false
|
||||
TEST16 = yes
|
||||
TEST17 = no
|
||||
|
||||
## Booleans are case-insensitive
|
||||
TEST18 = True
|
||||
TEST19 = False
|
||||
TEST20 = YES
|
||||
TEST21 = NO
|
||||
|
||||
TEST22 = "true" # "true" -- `string` type
|
||||
TEST23 = "YES" # "YES" -- `string` type
|
||||
TEST24 = 'NO' # "NO" -- `string` type
|
||||
|
||||
# Null values
|
||||
TEST25 =
|
||||
TEST26 = null
|
||||
|
||||
# Variables
|
||||
TEST27 = 'hello'
|
||||
TEST28 = ${TEST27} # 'hello'
|
||||
|
||||
TEST29 = 1
|
||||
TEST30 = 2
|
||||
TEST31 = ${TEST29} # 1 -- `int` type
|
||||
TEST32 = "${TEST29}" # 1 -- `string` type
|
||||
TEST33 = ${TEST29} ${TEST30} # 1 2 -- `string` type
|
||||
|
||||
TEST34 = foo
|
||||
TEST35 = bar
|
||||
TEST36 = ${TEST34}/${TEST35} # foo/bar -- `string` type
|
||||
|
||||
TEST37 = "foo"
|
||||
TEST38 = 'bar'
|
||||
TEST39 = "hello ${TEST37} and ${TEST38}" # hello foo and bar -- `string` type
|
||||
|
||||
TEST40 = true
|
||||
TEST41 = false
|
||||
TEST42 = ${TEST40} # true -- `bool` type
|
||||
TEST43 = ${TEST40} ${TEST41} # true false -- `string` type
|
||||
|
||||
TEST44 = null
|
||||
TEST45 = ${TEST44} # null -- `null` type
|
||||
TEST46 = "${TEST44}" # '' -- `string` type
|
||||
TEST46_5 = '${TEST44}' # '' -- `string` type
|
||||
|
||||
TEST47=foo
|
||||
TEST48=${TEST47:=bar}
|
||||
TEST49=${TEST50:=foo}
|
||||
TEST51=${TEST52:-foo}
|
||||
TEST53=null
|
||||
TEST54=${TEST53=foo}
|
||||
TEST55=null
|
||||
TEST56=${TEST55-foo}
|
||||
TEST57=${TEST58:=""}
|
||||
TEST59=${TEST60:=null} # TEST59 = null TEST60 = null -- both `null` types
|
||||
TEST61=${TEST62:=true} # TEST61 = true TEST62 = true -- both `bool` types
|
||||
|
||||
# Comments
|
||||
TEST63 = hello # comment
|
||||
TEST64 = "hello # comment"
|
||||
TEST65 = "hello" #comment
|
||||
TEST66 = #comment
|
||||
TEST67 = "#comment"
|
||||
TEST68 = thisisnota#comment
|
||||
```
|
||||
|
||||
The result from this library and the expected result of the above is:
|
||||
|
||||
```php
|
||||
array(
|
||||
"TEST1" => "value",
|
||||
"TEST2" => "value",
|
||||
"TEST3" => "value",
|
||||
"TEST4" => "value",
|
||||
"TEST5" => "value value",
|
||||
"TEST6" => "value \n value",
|
||||
"TEST7" => 'value "value" value',
|
||||
"TEST8" => "value",
|
||||
"TEST9" => "value ' value ' value",
|
||||
"TEST10" => 1,
|
||||
"TEST11" => 1.1,
|
||||
"TEST12" => "33 33",
|
||||
"TEST13" => "33",
|
||||
"TEST14" => true,
|
||||
"TEST15" => false,
|
||||
"TEST16" => true,
|
||||
"TEST17" => false,
|
||||
"TEST18" => true,
|
||||
"TEST19" => false,
|
||||
"TEST20" => true,
|
||||
"TEST21" => false,
|
||||
"TEST22" => "true",
|
||||
"TEST23" => "YES",
|
||||
"TEST24" => 'NO',
|
||||
"TEST25" => null,
|
||||
"TEST26" => null,
|
||||
"TEST27" => "hello",
|
||||
"TEST28" => "hello",
|
||||
"TEST29" => 1,
|
||||
"TEST30" => 2,
|
||||
"TEST31" => 1,
|
||||
"TEST32" => "1",
|
||||
"TEST33" => "1 2",
|
||||
"TEST34" => "foo",
|
||||
"TEST35" => "bar",
|
||||
"TEST36" => "foo/bar",
|
||||
"TEST37" => "foo",
|
||||
"TEST38" => 'bar',
|
||||
"TEST39" => "hello foo and bar",
|
||||
"TEST40" => true,
|
||||
"TEST41" => false,
|
||||
"TEST42" => true,
|
||||
"TEST43" => "true false",
|
||||
"TEST44" => null,
|
||||
"TEST45" => null,
|
||||
"TEST46" => "",
|
||||
"TEST46_5" => "${TEST44}",
|
||||
'TEST47' => 'foo',
|
||||
'TEST48' => 'foo',
|
||||
'TEST50' => 'foo',
|
||||
'TEST49' => 'foo',
|
||||
'TEST51' => 'foo',
|
||||
'TEST53' => null,
|
||||
'TEST54' => null,
|
||||
'TEST55' => null,
|
||||
'TEST56' => null,
|
||||
'TEST58' => '',
|
||||
'TEST57' => '',
|
||||
'TEST60' => null,
|
||||
'TEST59' => null,
|
||||
'TEST62' => true,
|
||||
'TEST61' => true,
|
||||
'TEST63' => 'hello # comment',
|
||||
'TEST64' => 'hello',
|
||||
'TEST66' => null,
|
||||
'TEST67' => '#comment',
|
||||
'TEST68' => 'thisisnota#comment',
|
||||
);
|
||||
```
|
||||
## Notes
|
||||
|
||||
### Source
|
||||
|
||||
If you need the .env variables in other applications, you can `source` the env, but make sure it's valid bash syntax, as this parser allows a more relaxed form of bash syntax.
|
||||
|
||||
```bash
|
||||
source .env
|
||||
```
|
||||
|
||||
This library will always be able to parse bash syntax, but for now the opposite (env syntax -> bash syntax) may not be true, however this is being worked on to bring a strict parser version for `3.0`
|
||||
|
||||
## Other library comparisons
|
||||
|
||||
The difference between this library and other similar libraries:
|
||||
|
||||
#### `zrcing/phpenv`:
|
||||
- Converts all value types to string
|
||||
- Does not support `null` values
|
||||
- Does not support `int`, `float` or `bool` types
|
||||
- Does not support variables
|
||||
|
||||
#### `Dotenv\Dotenv`:
|
||||
- Does not support unquoted values like `33 33`, this should be cast to string. See `TEST12`
|
||||
- Does not support concatenation of variables unquoted like `${VAR} ${VAR2}`, this should be cast to string. See `TEST33`
|
||||
- Both of the above crash `Dotenv` without a helpful exception
|
||||
- Converts all value types to string
|
||||
- Does not support `null` values
|
||||
- Does not support `int`, `float` or `bool` types
|
||||
- Does not support variables
|
||||
- Does not support [parameter expansions](#parameter-expansion)
|
||||
- Does not support inline comments where there is no value. See `TEST66`
|
||||
|
||||
|
||||
## Todo
|
||||
- [Other bash parameter expansions](http://wiki.bash-hackers.org/syntax/pe#display_error_if_null_or_unset)
|
||||
|
||||
## Change log
|
||||
|
||||
Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
|
||||
|
||||
## Testing
|
||||
|
||||
``` bash
|
||||
$ composer test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Please see [CONTRIBUTING](CONTRIBUTING.md) and [CONDUCT](CONDUCT.md) for details.
|
||||
|
||||
## Security
|
||||
|
||||
If you discover any security related issues, please email hello@milescroxford.com instead of using the issue tracker.
|
||||
|
||||
## Credits
|
||||
|
||||
- [m1][link-author]
|
||||
- [All Contributors][link-contributors]
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
|
||||
|
||||
[ico-version]: https://img.shields.io/packagist/v/m1/Env.svg?style=flat-square
|
||||
[ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square
|
||||
[ico-travis]: https://img.shields.io/travis/m1/Env/master.svg?style=flat-square
|
||||
[ico-scrutinizer]: https://img.shields.io/scrutinizer/coverage/g/m1/Env.svg?style=flat-square
|
||||
[ico-hhvm]: https://img.shields.io/hhvm/m1/Env.svg?style=flat-square
|
||||
[ico-code-quality]: https://img.shields.io/scrutinizer/g/m1/Env.svg?style=flat-square
|
||||
[ico-downloads]: https://img.shields.io/packagist/dt/m1/Env.svg?style=flat-square
|
||||
[ico-sensio]: https://insight.sensiolabs.com/projects/1fb8cbab-f611-45b5-8a45-0113e433eab7/big.png
|
||||
|
||||
[link-packagist]: https://packagist.org/packages/m1/Env
|
||||
[link-travis]: https://travis-ci.org/m1/Env
|
||||
[link-scrutinizer]: https://scrutinizer-ci.com/g/m1/Env/code-structure
|
||||
[link-code-quality]: https://scrutinizer-ci.com/g/m1/Env
|
||||
[link-downloads]: https://packagist.org/packages/m1/Env
|
||||
[link-author]: https://github.com/m1
|
||||
[link-contributors]: ../../contributors
|
||||
[link-sensio]: https://insight.sensiolabs.com/projects/1fb8cbab-f611-45b5-8a45-0113e433eab7
|
||||
Vendored
+51
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "m1/env",
|
||||
"description": "Env is a lightweight library bringing .env file parser compatibility to PHP. In short - it enables you to read .env files with PHP.",
|
||||
"keywords": [
|
||||
"m1",
|
||||
"env",
|
||||
"loader",
|
||||
"config",
|
||||
".env",
|
||||
"dotenv",
|
||||
"support",
|
||||
"parser"
|
||||
],
|
||||
"homepage": "https://github.com/m1/Env",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Miles Croxford",
|
||||
"email": "hello@milescroxford.com",
|
||||
"homepage": "http://milescroxford.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php" : ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit" : "4.*",
|
||||
"scrutinizer/ocular": "~1.1",
|
||||
"squizlabs/php_codesniffer": "^2.3"
|
||||
},
|
||||
"suggest": {
|
||||
"josegonzalez/dotenv": "For loading of .env",
|
||||
"m1/vars": "For loading of configs"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"M1\\Env\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"M1\\Env\\Test\\": "tests"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit",
|
||||
"check-codestyle": "phpcs -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src tests",
|
||||
"fix-codestyle": "phpcbf -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src tests"
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the m1\env library
|
||||
*
|
||||
* (c) m1 <hello@milescroxford.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package m1/env
|
||||
* @version 2.0.0
|
||||
* @author Miles Croxford <hello@milescroxford.com>
|
||||
* @copyright Copyright (c) Miles Croxford <hello@milescroxford.com>
|
||||
* @license http://github.com/m1/env/blob/master/LICENSE.md
|
||||
* @link http://github.com/m1/env/blob/master/README.md Documentation
|
||||
*/
|
||||
|
||||
namespace M1\Env\Exception;
|
||||
|
||||
/**
|
||||
* Env ParseException
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
class ParseException extends \ErrorException
|
||||
{
|
||||
/**
|
||||
* Constructs a ParseException
|
||||
*
|
||||
* @param string $message The value to parse
|
||||
* @param string $line The line of the value
|
||||
* @param int $line_num The line num of the value
|
||||
*/
|
||||
public function __construct($message, $line = null, $line_num = null)
|
||||
{
|
||||
$message = $this->createMessage($message, $line, $line_num);
|
||||
|
||||
parent::__construct($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ParseException message
|
||||
*
|
||||
* @param string $message The value to parse
|
||||
* @param string $line The line of the value
|
||||
* @param int $line_num The line num of the value
|
||||
*
|
||||
* @return string The exception message
|
||||
*/
|
||||
private function createMessage($message, $line, $line_num)
|
||||
{
|
||||
if (!is_null($line)) {
|
||||
$message .= sprintf(" near %s", $line);
|
||||
}
|
||||
|
||||
if (!is_null($line_num)) {
|
||||
$message .= sprintf(" at line %d", $line_num);
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the m1\env library
|
||||
*
|
||||
* (c) m1 <hello@milescroxford.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package m1/env
|
||||
* @version 2.0.0
|
||||
* @author Miles Croxford <hello@milescroxford.com>
|
||||
* @copyright Copyright (c) Miles Croxford <hello@milescroxford.com>
|
||||
* @license http://github.com/m1/env/blob/master/LICENSE.md
|
||||
* @link http://github.com/m1/env/blob/master/README.md Documentation
|
||||
*/
|
||||
|
||||
namespace M1\Env\Helper;
|
||||
|
||||
/**
|
||||
* The class for string helping
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class StringHelper
|
||||
{
|
||||
/**
|
||||
* The bool variants available in .env
|
||||
*
|
||||
* @var array $bool_variants
|
||||
*/
|
||||
private static $bool_variants = array(
|
||||
'true', 'false', 'yes', 'no'
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns if value is a bool
|
||||
*
|
||||
* @param string $value The value to test
|
||||
*
|
||||
* @return bool Is a value a bool
|
||||
*/
|
||||
public function isBool($value)
|
||||
{
|
||||
return in_array(strtolower($value), self::$bool_variants);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the bool is in a string
|
||||
*
|
||||
* @param string $value The value to test
|
||||
* @param bool $quoted_string Is the context a quoted string
|
||||
* @param int $word_count The amount of words in the sentence
|
||||
*
|
||||
* @return bool Is a value a bool in a string
|
||||
*/
|
||||
public function isBoolInString($value, $quoted_string, $word_count)
|
||||
{
|
||||
return (is_bool($value)) && ($quoted_string || $word_count >= 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if value is null
|
||||
*
|
||||
* @param string $value The value to test
|
||||
*
|
||||
* @return bool Is a value null
|
||||
*/
|
||||
public function isNull($value)
|
||||
{
|
||||
return $value === 'null';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if value is number
|
||||
*
|
||||
* @param string $value The value to test
|
||||
*
|
||||
* @return bool Is a value a number
|
||||
*/
|
||||
public function isNumber($value)
|
||||
{
|
||||
return is_numeric($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if value is a string
|
||||
*
|
||||
* @param string $value The value to test
|
||||
*
|
||||
* @return bool Is a value a string
|
||||
*/
|
||||
public function isString($value)
|
||||
{
|
||||
return $this->startsWith('\'', $value) || $this->startsWith('"', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if variable value is a clone, e.g. BOOL = $(BOOL_1)
|
||||
*
|
||||
* @param string $value The value to test
|
||||
* @param array $matches The matches of the variables
|
||||
* @param bool $quoted_string If the value is in a quoted string
|
||||
*
|
||||
* @return bool Is a value null
|
||||
*/
|
||||
public function isVariableClone($value, $matches, $quoted_string)
|
||||
{
|
||||
return (count($matches[0]) === 1) && $value == $matches[0][0] && !$quoted_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if value starts with a value
|
||||
*
|
||||
* @param string $string The value to search for
|
||||
* @param string $line The line to test
|
||||
*
|
||||
* @return bool Returns if the line starts with value
|
||||
*/
|
||||
public function startsWith($string, $line)
|
||||
{
|
||||
return $string === "" || strrpos($line, $string, -strlen($line)) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if value starts with a number
|
||||
*
|
||||
* @param string $line The line to test
|
||||
*
|
||||
* @return bool Returns if the line starts with a number
|
||||
*/
|
||||
public function startsWithNumber($line)
|
||||
{
|
||||
return is_numeric(substr($line, 0, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips comments from a value
|
||||
*
|
||||
* @param string $value The value to strip comments from
|
||||
*
|
||||
* @return string value
|
||||
*/
|
||||
public function stripComments($value)
|
||||
{
|
||||
$value = explode(" #", $value, 2);
|
||||
return trim($value[0]);
|
||||
}
|
||||
}
|
||||
Vendored
+244
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the m1\env library
|
||||
*
|
||||
* (c) m1 <hello@milescroxford.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package m1/env
|
||||
* @version 2.0.0
|
||||
* @author Miles Croxford <hello@milescroxford.com>
|
||||
* @copyright Copyright (c) Miles Croxford <hello@milescroxford.com>
|
||||
* @license http://github.com/m1/env/blob/master/LICENSE.md
|
||||
* @link http://github.com/m1/env/blob/master/README.md Documentation
|
||||
*/
|
||||
|
||||
namespace M1\Env;
|
||||
|
||||
use M1\Env\Exception\ParseException;
|
||||
use M1\Env\Helper\StringHelper;
|
||||
use M1\Env\Parser\ValueParser;
|
||||
use M1\Env\Parser\KeyParser;
|
||||
|
||||
/**
|
||||
* The .env parser
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
class Parser
|
||||
{
|
||||
/**
|
||||
* The Env key parser
|
||||
*
|
||||
* @var \M1\Env\Parser\KeyParser $key_parser
|
||||
*/
|
||||
private $key_parser;
|
||||
|
||||
/**
|
||||
* The line num of the current value
|
||||
*
|
||||
* @var int $line_num
|
||||
*/
|
||||
public $line_num;
|
||||
|
||||
/**
|
||||
* The current parsed values/lines
|
||||
*
|
||||
* @var array $lines
|
||||
*/
|
||||
public $lines = array();
|
||||
|
||||
/**
|
||||
* The String helper class
|
||||
*
|
||||
* @var \M1\Env\Helper\StringHelper $string_helper
|
||||
*/
|
||||
public $string_helper;
|
||||
|
||||
|
||||
/**
|
||||
* The Env value parser
|
||||
*
|
||||
* @var \M1\Env\Parser\ValueParser $value_parser
|
||||
*/
|
||||
public $value_parser;
|
||||
|
||||
/**
|
||||
* The parser constructor
|
||||
*
|
||||
* @param string $content The content to parse
|
||||
* @param array $context Variables context
|
||||
*/
|
||||
public function __construct($content, array $context = array())
|
||||
{
|
||||
$this->key_parser = new KeyParser($this);
|
||||
$this->value_parser = new ValueParser($this, $context);
|
||||
$this->string_helper = new StringHelper();
|
||||
|
||||
$this->doParse($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the .env and returns the contents statically
|
||||
*
|
||||
* @param string $content The content to parse
|
||||
* @param array $context Variables context
|
||||
*
|
||||
* @return array The .env contents
|
||||
*/
|
||||
public static function parse($content, array $context = array())
|
||||
{
|
||||
$parser = new Parser($content, $context);
|
||||
|
||||
return $parser->getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the .env, parses it then returns the contents
|
||||
*
|
||||
* @param string $content The content to parse
|
||||
*
|
||||
* @return array The .env contents
|
||||
*/
|
||||
protected function doParse($content)
|
||||
{
|
||||
$raw_lines = array_filter($this->makeLines($content), 'strlen');
|
||||
|
||||
if (empty($raw_lines)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->parseContent($raw_lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits the string into an array
|
||||
*
|
||||
* @param string $content The string content to split
|
||||
*
|
||||
* @return array The array of lines to parse
|
||||
*/
|
||||
private function makeLines($content)
|
||||
{
|
||||
return explode("\n", str_replace(array("\r\n", "\n\r", "\r"), "\n", $content));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the .env line by line
|
||||
*
|
||||
* @param array $raw_lines The raw content of the file
|
||||
*
|
||||
* @throws \M1\Env\Exception\ParseException If the file does not have a key=value structure
|
||||
*
|
||||
* @return array The .env contents
|
||||
*/
|
||||
private function parseContent(array $raw_lines)
|
||||
{
|
||||
$this->lines = array();
|
||||
$this->line_num = 0;
|
||||
|
||||
foreach ($raw_lines as $raw_line) {
|
||||
$this->line_num++;
|
||||
|
||||
if ($this->string_helper->startsWith('#', $raw_line) || !$raw_line) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->parseLine($raw_line);
|
||||
}
|
||||
|
||||
return $this->lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a line of the .env
|
||||
*
|
||||
* @param string $raw_line The raw content of the line
|
||||
*
|
||||
* @return array The parsed lines
|
||||
*/
|
||||
private function parseLine($raw_line)
|
||||
{
|
||||
$raw_line = $this->parseExport($raw_line);
|
||||
|
||||
list($key, $value) = $this->parseKeyValue($raw_line);
|
||||
|
||||
$key = $this->key_parser->parse($key);
|
||||
|
||||
if (!is_string($key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->lines[$key] = $this->value_parser->parse($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a export line of the .env
|
||||
*
|
||||
* @param string $raw_line The raw content of the line
|
||||
*
|
||||
* @throws \M1\Env\Exception\ParseException If the file does not have a key=value structure
|
||||
*
|
||||
* @return string The parsed line
|
||||
*/
|
||||
private function parseExport($raw_line)
|
||||
{
|
||||
$line = trim($raw_line);
|
||||
|
||||
if ($this->string_helper->startsWith("export", $line)) {
|
||||
$export_line = explode("export", $raw_line, 2);
|
||||
|
||||
if (count($export_line) !== 2 || empty($export_line[1])) {
|
||||
throw new ParseException(
|
||||
'You must have a export key = value',
|
||||
$raw_line,
|
||||
$this->line_num
|
||||
);
|
||||
}
|
||||
|
||||
$line = trim($export_line[1]);
|
||||
}
|
||||
|
||||
return $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key = value items from the line
|
||||
*
|
||||
* @param string $raw_line The raw content of the line
|
||||
*
|
||||
* @throws \M1\Env\Exception\ParseException If the line does not have a key=value structure
|
||||
*
|
||||
* @return array The parsed lines
|
||||
*/
|
||||
private function parseKeyValue($raw_line)
|
||||
{
|
||||
$key_value = explode("=", $raw_line, 2);
|
||||
|
||||
if (count($key_value) !== 2) {
|
||||
throw new ParseException(
|
||||
'You must have a key = value',
|
||||
$raw_line,
|
||||
$this->line_num
|
||||
);
|
||||
}
|
||||
|
||||
return $key_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents of the .env
|
||||
*
|
||||
* @return array The .env contents
|
||||
*/
|
||||
public function getContent($keyName = null)
|
||||
{
|
||||
if (!is_null($keyName)) {
|
||||
return (array_key_exists($keyName, $this->lines)) ? $this->lines[$keyName] : null;
|
||||
}
|
||||
return $this->lines;
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the m1\env library
|
||||
*
|
||||
* (c) m1 <hello@milescroxford.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package m1/env
|
||||
* @version 2.0.0
|
||||
* @author Miles Croxford <hello@milescroxford.com>
|
||||
* @copyright Copyright (c) Miles Croxford <hello@milescroxford.com>
|
||||
* @license http://github.com/m1/env/blob/master/LICENSE.md
|
||||
* @link http://github.com/m1/env/blob/master/README.md Documentation
|
||||
*/
|
||||
|
||||
namespace M1\Env\Parser;
|
||||
|
||||
/**
|
||||
* The abstract parser for Env
|
||||
*
|
||||
* @since 0.2.0
|
||||
*/
|
||||
abstract class AbstractParser
|
||||
{
|
||||
/**
|
||||
* The parent parser
|
||||
*
|
||||
* @var \M1\Env\Parser $parser
|
||||
*/
|
||||
protected $parser;
|
||||
|
||||
/**
|
||||
* The abstract parser constructor for Env
|
||||
*
|
||||
* @param \M1\Env\Parser $parser The parent parser
|
||||
*/
|
||||
public function __construct($parser)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the m1\env library
|
||||
*
|
||||
* (c) m1 <hello@milescroxford.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package m1/env
|
||||
* @version 2.0.0
|
||||
* @author Miles Croxford <hello@milescroxford.com>
|
||||
* @copyright Copyright (c) Miles Croxford <hello@milescroxford.com>
|
||||
* @license http://github.com/m1/env/blob/master/LICENSE.md
|
||||
* @link http://github.com/m1/env/blob/master/README.md Documentation
|
||||
*/
|
||||
|
||||
namespace M1\Env\Parser;
|
||||
|
||||
use M1\Env\Exception\ParseException;
|
||||
|
||||
/**
|
||||
* The key parser for Env
|
||||
*
|
||||
* @since 0.2.0
|
||||
*/
|
||||
class KeyParser extends AbstractParser
|
||||
{
|
||||
/**
|
||||
* Parses a .env key
|
||||
*
|
||||
* @param string $key The key string
|
||||
*
|
||||
* @throws \M1\Env\Exception\ParseException If key contains a character that isn't alphanumeric or a _
|
||||
*
|
||||
* @return string|false The parsed key, or false if the key is a comment
|
||||
*/
|
||||
public function parse($key)
|
||||
{
|
||||
$key = trim($key);
|
||||
|
||||
if ($this->parser->string_helper->startsWith('#', $key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ctype_alnum(str_replace('_', '', $key)) || $this->parser->string_helper->startsWithNumber($key)) {
|
||||
throw new ParseException(
|
||||
sprintf('Key can only contain alphanumeric and underscores and can not start with a number: %s', $key),
|
||||
$key,
|
||||
$this->parser->line_num
|
||||
);
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
+264
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the m1\env library
|
||||
*
|
||||
* (c) m1 <hello@milescroxford.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package m1/env
|
||||
* @version 2.0.0
|
||||
* @author Miles Croxford <hello@milescroxford.com>
|
||||
* @copyright Copyright (c) Miles Croxford <hello@milescroxford.com>
|
||||
* @license http://github.com/m1/env/blob/master/LICENSE.md
|
||||
* @link http://github.com/m1/env/blob/master/README.md Documentation
|
||||
*/
|
||||
|
||||
namespace M1\Env\Parser;
|
||||
|
||||
use M1\Env\Exception\ParseException;
|
||||
|
||||
/**
|
||||
* The value parser for Env
|
||||
*
|
||||
* @since 0.2.0
|
||||
*/
|
||||
class ValueParser extends AbstractParser
|
||||
{
|
||||
/**
|
||||
* The regex to get the content between double quote (") strings, ignoring escaped quotes.
|
||||
* Unescaped: "(?:[^"\\]*(?:\\.)?)*"
|
||||
*
|
||||
* @var string REGEX_QUOTE_DOUBLE_STRING
|
||||
*/
|
||||
const REGEX_QUOTE_DOUBLE_STRING = '"(?:[^\"\\\\]*(?:\\\\.)?)*\"';
|
||||
|
||||
/**
|
||||
* The regex to get the content between single quote (') strings, ignoring escaped quotes
|
||||
* Unescaped: '(?:[^'\\]*(?:\\.)?)*'
|
||||
*
|
||||
* @var string REGEX_QUOTE_SINGLE_STRING
|
||||
*/
|
||||
const REGEX_QUOTE_SINGLE_STRING = "'(?:[^'\\\\]*(?:\\\\.)?)*'";
|
||||
|
||||
/**
|
||||
* The value types that Env supports
|
||||
*
|
||||
* @var array $value_types
|
||||
*/
|
||||
private static $value_types = array(
|
||||
'string',
|
||||
'bool',
|
||||
'number',
|
||||
'null',
|
||||
);
|
||||
|
||||
/**
|
||||
* The map to convert escaped characters into real characters
|
||||
*
|
||||
* @var array $character_map
|
||||
*/
|
||||
private static $character_map = array(
|
||||
"\\n" => "\n",
|
||||
"\\\"" => "\"",
|
||||
'\\\'' => "'",
|
||||
'\\t' => "\t"
|
||||
);
|
||||
|
||||
/**
|
||||
* The parser for variables
|
||||
*
|
||||
* @var \M1\Env\Parser\VariableParser $variable_parser
|
||||
*/
|
||||
private $variable_parser;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param \M1\Env\Parser $parser The parent parser
|
||||
* @param array $context Variables context
|
||||
*/
|
||||
public function __construct($parser, array $context = array())
|
||||
{
|
||||
parent::__construct($parser);
|
||||
|
||||
$this->variable_parser = new VariableParser($parser, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a .env value
|
||||
*
|
||||
* @param string $value The value to parse
|
||||
*
|
||||
* @return string|null The parsed key, or null if the key is a comment
|
||||
*/
|
||||
public function parse($value)
|
||||
{
|
||||
$value = trim($value);
|
||||
|
||||
if ($this->parser->string_helper->startsWith('#', $value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->parseValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a .env value
|
||||
*
|
||||
* @param string $value The value to parse
|
||||
*
|
||||
* @return string|null The parsed value, or null if the value is null
|
||||
*
|
||||
* @uses parseString
|
||||
* @uses parseNull
|
||||
* @uses parseBool
|
||||
* @uses parseNumber
|
||||
*/
|
||||
private function parseValue($value)
|
||||
{
|
||||
foreach (self::$value_types as $type) {
|
||||
$parsed_value = $value;
|
||||
|
||||
if ($type !== 'string') {
|
||||
$parsed_value = $this->parser->string_helper->stripComments($value);
|
||||
}
|
||||
|
||||
list($is_function, $parse_function) = $this->fetchFunctionNames($type);
|
||||
|
||||
if ($this->parser->string_helper->$is_function($parsed_value)) {
|
||||
return $this->$parse_function($parsed_value);
|
||||
}
|
||||
}
|
||||
|
||||
return (isset($parsed_value)) ? $this->parseUnquotedString($parsed_value) : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the functions for the value type
|
||||
*
|
||||
* @param string $type The value type
|
||||
*
|
||||
* @return string[] The is and parse function names
|
||||
*/
|
||||
private function fetchFunctionNames($type)
|
||||
{
|
||||
$type = ucfirst($type);
|
||||
|
||||
return array(
|
||||
'is'.$type,
|
||||
'parse'.$type
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a .env string
|
||||
*
|
||||
* @param string $value The value to parse
|
||||
*
|
||||
* @return string The parsed string
|
||||
*/
|
||||
private function parseString($value)
|
||||
{
|
||||
$single = false;
|
||||
$regex = self::REGEX_QUOTE_DOUBLE_STRING;
|
||||
$symbol = '"';
|
||||
|
||||
if ($this->parser->string_helper->startsWith('\'', $value)) {
|
||||
$single = true;
|
||||
$regex = self::REGEX_QUOTE_SINGLE_STRING;
|
||||
$symbol = "'";
|
||||
}
|
||||
|
||||
$matches = $this->fetchStringMatches($value, $regex, $symbol);
|
||||
|
||||
$value = trim($matches[0], $symbol);
|
||||
$value = strtr($value, self::$character_map);
|
||||
|
||||
return ($single) ? $value : $this->variable_parser->parse($value, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the regex matches in the string
|
||||
*
|
||||
* @param string $regex The regex to use
|
||||
* @param string $value The value to parse
|
||||
* @param string $symbol The symbol we're parsing for
|
||||
*
|
||||
* @throws \M1\Env\Exception\ParseException If the string has a missing end quote
|
||||
*
|
||||
* @return string[] The matches based on the regex and the value
|
||||
*/
|
||||
private function fetchStringMatches($value, $regex, $symbol)
|
||||
{
|
||||
if (!preg_match('/'.$regex.'/', $value, $matches)) {
|
||||
throw new ParseException(
|
||||
sprintf('Missing end %s quote', $symbol),
|
||||
$value,
|
||||
$this->parser->line_num
|
||||
);
|
||||
}
|
||||
|
||||
return $matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a .env null value
|
||||
*
|
||||
* @param string $value The value to parse
|
||||
*
|
||||
* @return null Null value
|
||||
*/
|
||||
private function parseNull($value)
|
||||
{
|
||||
return (is_null($value) || $value === "null") ? null : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a .env unquoted string
|
||||
*
|
||||
* @param string $value The value to parse
|
||||
*
|
||||
* @return string The parsed string
|
||||
*/
|
||||
private function parseUnquotedString($value)
|
||||
{
|
||||
if ($value === "") {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->variable_parser->parse($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a .env bool
|
||||
*
|
||||
* @param string $value The value to parse
|
||||
*
|
||||
* @return bool The parsed bool
|
||||
*/
|
||||
private function parseBool($value)
|
||||
{
|
||||
$value = strtolower($value);
|
||||
|
||||
return $value === "true" || $value === "yes";
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a .env number
|
||||
*
|
||||
* @param string $value The value to parse
|
||||
*
|
||||
* @return int|float The parsed bool
|
||||
*/
|
||||
private function parseNumber($value)
|
||||
{
|
||||
if (strpos($value, '.') !== false) {
|
||||
return (float) $value;
|
||||
}
|
||||
|
||||
return (int) $value;
|
||||
}
|
||||
}
|
||||
+358
@@ -0,0 +1,358 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the m1\env library
|
||||
*
|
||||
* (c) m1 <hello@milescroxford.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package m1/env
|
||||
* @version 2.0.0
|
||||
* @author Miles Croxford <hello@milescroxford.com>
|
||||
* @copyright Copyright (c) Miles Croxford <hello@milescroxford.com>
|
||||
* @license http://github.com/m1/env/blob/master/LICENSE.md
|
||||
* @link http://github.com/m1/env/blob/master/README.md Documentation
|
||||
*/
|
||||
|
||||
namespace M1\Env\Parser;
|
||||
|
||||
use M1\Env\Exception\ParseException;
|
||||
|
||||
/**
|
||||
* The value parser for Env
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class VariableParser extends AbstractParser
|
||||
{
|
||||
/**
|
||||
* The regex to get variables '$(VARIABLE)' in .env
|
||||
* Unescaped: ${(.*?)}
|
||||
*
|
||||
* @var string REGEX_ENV_VARIABLE
|
||||
*/
|
||||
const REGEX_ENV_VARIABLE = '\\${(.*?)}';
|
||||
|
||||
/**
|
||||
* The symbol for the assign default value parameter expansion
|
||||
*
|
||||
* @var string SYMBOL_ASSIGN_DEFAULT_VALUE
|
||||
*/
|
||||
const SYMBOL_ASSIGN_DEFAULT_VALUE = '=';
|
||||
|
||||
/**
|
||||
* The symbol for the default value parameter expansion
|
||||
*
|
||||
* @var string SYMBOL_DEFAULT_VALUE
|
||||
*/
|
||||
const SYMBOL_DEFAULT_VALUE = '-';
|
||||
|
||||
/**
|
||||
* Variables context
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $context;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param \M1\Env\Parser $parser The parent parser
|
||||
* @param array $context Variables context
|
||||
*/
|
||||
public function __construct($parser, array $context = array())
|
||||
{
|
||||
parent::__construct($parser);
|
||||
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a .env variable
|
||||
*
|
||||
* @param string $value The value to parse
|
||||
* @param bool $quoted_string Is the value in a quoted string
|
||||
*
|
||||
* @return string The parsed value
|
||||
*/
|
||||
public function parse($value, $quoted_string = false)
|
||||
{
|
||||
$matches = $this->fetchVariableMatches($value);
|
||||
|
||||
if (is_array($matches)) {
|
||||
if ($this->parser->string_helper->isVariableClone($value, $matches, $quoted_string)) {
|
||||
return $this->fetchVariable($value, $matches[1][0], $matches, $quoted_string);
|
||||
}
|
||||
|
||||
$value = $this->doReplacements($value, $matches, $quoted_string);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get variable matches inside a string
|
||||
*
|
||||
* @param string $value The value to parse
|
||||
*
|
||||
* @return array The variable matches
|
||||
*/
|
||||
private function fetchVariableMatches($value)
|
||||
{
|
||||
preg_match_all('/' . self::REGEX_ENV_VARIABLE . '/', $value, $matches);
|
||||
|
||||
if (!is_array($matches) || !isset($matches[0]) || empty($matches[0])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a .env variable
|
||||
*
|
||||
* @param string $value The value to parse
|
||||
* @param string $variable_name The variable name to get
|
||||
* @param array $matches The matches of the variables
|
||||
* @param bool $quoted_string Is the value in a quoted string
|
||||
*
|
||||
* @return string The parsed value
|
||||
* @throws \M1\Env\Exception\ParseException If the variable can not be found
|
||||
*/
|
||||
private function fetchVariable($value, $variable_name, $matches, $quoted_string)
|
||||
{
|
||||
if ($this->hasParameterExpansion($variable_name)) {
|
||||
$replacement = $this->fetchParameterExpansion($variable_name);
|
||||
} elseif ($this->hasVariable($variable_name)) {
|
||||
$replacement = $this->getVariable($variable_name);
|
||||
} else {
|
||||
throw new ParseException(
|
||||
sprintf('Variable has not been defined: %s', $variable_name),
|
||||
$value,
|
||||
$this->parser->line_num
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->parser->string_helper->isBoolInString($replacement, $quoted_string, count($matches[0]))) {
|
||||
$replacement = ($replacement) ? 'true' : 'false';
|
||||
}
|
||||
|
||||
return $replacement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the variable has a parameter expansion
|
||||
*
|
||||
* @param string $variable The variable to check
|
||||
*
|
||||
* @return bool Does the variable have a parameter expansion
|
||||
*/
|
||||
private function hasParameterExpansion($variable)
|
||||
{
|
||||
if ((strpos($variable, self::SYMBOL_DEFAULT_VALUE) !== false) ||
|
||||
(strpos($variable, self::SYMBOL_ASSIGN_DEFAULT_VALUE) !== false)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and sets the parameter expansion
|
||||
*
|
||||
* @param string $variable_name The parameter expansion inside this to fetch
|
||||
*
|
||||
* @return string The parsed value
|
||||
*/
|
||||
private function fetchParameterExpansion($variable_name)
|
||||
{
|
||||
$parameter_type = $this->fetchParameterExpansionType($variable_name);
|
||||
|
||||
list($parameter_symbol, $empty_flag) = $this->fetchParameterExpansionSymbol($variable_name, $parameter_type);
|
||||
list($variable, $default) = $this->splitVariableDefault($variable_name, $parameter_symbol);
|
||||
|
||||
$value = $this->getVariable($variable);
|
||||
|
||||
return $this->parseVariableParameter(
|
||||
$variable,
|
||||
$default,
|
||||
$this->hasVariable($variable),
|
||||
$empty_flag && empty($value),
|
||||
$parameter_type
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the parameter expansion type
|
||||
*
|
||||
* @param string $variable_name The parameter expansion type to get from this
|
||||
*
|
||||
* @return string The parameter expansion type
|
||||
*/
|
||||
private function fetchParameterExpansionType($variable_name)
|
||||
{
|
||||
if (strpos($variable_name, self::SYMBOL_ASSIGN_DEFAULT_VALUE) !== false) {
|
||||
return 'assign_default_value';
|
||||
}
|
||||
|
||||
return 'default_value'; // self::DEFAULT_VALUE_SYMBOL
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the parameter type symbol
|
||||
*
|
||||
* @param string $variable_name The variable
|
||||
* @param string $type The type of parameter expansion
|
||||
*
|
||||
* @return array The symbol and if there is a empty check
|
||||
*/
|
||||
private function fetchParameterExpansionSymbol($variable_name, $type)
|
||||
{
|
||||
$class = new \ReflectionClass($this);
|
||||
$symbol = $class->getConstant('SYMBOL_'.strtoupper($type));
|
||||
$pos = strpos($variable_name, $symbol);
|
||||
|
||||
$check_empty = substr($variable_name, ($pos - 1), 1) === ":";
|
||||
|
||||
if ($check_empty) {
|
||||
$symbol = sprintf(":%s", $symbol);
|
||||
}
|
||||
|
||||
return array($symbol, $check_empty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits the parameter expansion into variable and default
|
||||
*
|
||||
* @param string $variable_name The variable name to split
|
||||
* @param string $parameter_symbol The parameter expansion symbol
|
||||
*
|
||||
* @throws \M1\Env\Exception\ParseException If the parameter expansion if not valid syntax
|
||||
*
|
||||
* @return array The split variable and default value
|
||||
*/
|
||||
private function splitVariableDefault($variable_name, $parameter_symbol)
|
||||
{
|
||||
$variable_default = explode($parameter_symbol, $variable_name, 2);
|
||||
|
||||
if (count($variable_default) !== 2 || empty($variable_default[1])) {
|
||||
throw new ParseException(
|
||||
'You must have valid parameter expansion syntax, eg. ${parameter:=word}',
|
||||
$variable_name,
|
||||
$this->parser->line_num
|
||||
);
|
||||
}
|
||||
|
||||
return array(trim($variable_default[0]), trim($variable_default[1]));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses and sets the variable and default if needed
|
||||
*
|
||||
* @param string $variable The variable to parse
|
||||
* @param string $default The default value
|
||||
* @param bool $exists Does the variable exist
|
||||
* @param bool $empty Is there the variable empty if exists and the empty flag is set
|
||||
* @param string $type The type of parameter expansion
|
||||
*
|
||||
* @return string The parsed value
|
||||
*/
|
||||
private function parseVariableParameter($variable, $default, $exists, $empty, $type)
|
||||
{
|
||||
if ($exists && !$empty) {
|
||||
return $this->getVariable($variable);
|
||||
}
|
||||
|
||||
return $this->assignVariableParameterDefault($variable, $default, $empty, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and sets the variable parameter to default
|
||||
*
|
||||
* @param string $variable The variable to parse
|
||||
* @param string $default The default value
|
||||
* @param bool $empty Is there the variable empty if exists and the empty flag is set
|
||||
* @param string $type The type of parameter expansion
|
||||
*
|
||||
* @return string The parsed default value
|
||||
*/
|
||||
private function assignVariableParameterDefault($variable, $default, $empty, $type)
|
||||
{
|
||||
$default = $this->parser->value_parser->parse($default);
|
||||
|
||||
if ($type === "assign_default_value" && $empty) {
|
||||
$this->parser->lines[$variable] = $default;
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a variable exists
|
||||
*
|
||||
* @param string $variable The variable name to get
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasVariable($variable)
|
||||
{
|
||||
if (array_key_exists($variable, $this->parser->lines)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (array_key_exists($variable, $this->context)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get variable value
|
||||
*
|
||||
* @param string $variable
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function getVariable($variable)
|
||||
{
|
||||
if (array_key_exists($variable, $this->parser->lines)) {
|
||||
return $this->parser->lines[$variable];
|
||||
}
|
||||
|
||||
if (array_key_exists($variable, $this->context)) {
|
||||
return $this->context[$variable];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the variable replacements
|
||||
*
|
||||
* @param string $value The value to throw an error with if doesn't exist
|
||||
* @param array $matches The matches of the variables
|
||||
* @param bool $quoted_string Is the value in a quoted string
|
||||
*
|
||||
* @return string The parsed value
|
||||
*/
|
||||
public function doReplacements($value, $matches, $quoted_string)
|
||||
{
|
||||
$replacements = array();
|
||||
|
||||
for ($i = 0; $i <= (count($matches[0]) - 1); $i++) {
|
||||
$replacement = $this->fetchVariable($value, $matches[1][$i], $matches, $quoted_string);
|
||||
$replacements[$matches[0][$i]] = $replacement;
|
||||
}
|
||||
|
||||
if (!empty($replacements)) {
|
||||
$value = strtr($value, $replacements);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user