I am quite surprised at the accepted answer here, and the number of its elevations. With the exception of Marcio Mazzukato's answer, there is no discussion of the relative strengths / weaknesses of any of several approaches.
The options that I see are as follows:
File-based mechanisms
This requires your code to look in certain places to find the ini file. This is a difficult problem to solve, which always arises in large PHP applications. However, you will likely have to solve the problem in order to find PHP code that is included / reused at runtime.
General approaches to this are to always use relative directories or look up from the current directory to find a file exclusively named in the application’s base directory.
Typical file formats used for configuration files are PHP code, ini-formatted files, JSON, XML, YAML, and serialized PHP
Php code
This provides tremendous flexibility for representing various data structures and (provided that it is processed using include or require), the analyzed code will be accessible from the operation code cache, which gives an advantage in performance.
include_path provides a means to abstract away potential file locations without relying on additional code.
On the other hand, one of the main reasons for sharing configuration from code is separation of duties. It provides a route for entering additional code at run time.
If the configuration is created from a tool, it may be possible to check the data in the tool, but there is no standard function to delete data for embedding in PHP code, as it exists for HTML, URLs, MySQL statements, shell commands ....
Serialized data This is relatively effective for small configuration volumes (up to 200 units) and allows you to use any PHP data structure. To create / analyze a data file, very little code is required (so you can instead spend your efforts on writing the file only with the appropriate authorization).
Resetting the contents written to the file is processed automatically.
Since you can serialize objects, this makes it possible to call the code simply by reading the configuration file (magic method __wakeup).
Structured file
Saving as an INI file, as suggested by Marcel or JSON or XML, also provides a simple api to map the file to the PHP data structure (and, with the exception of XML, to delete the data and create the file) while eliminating the vulnerability of calling code using PHP serialized data .
It will have similar performance characteristics with serialized data.
Database repository
This is best considered when you have a huge configuration, but selectively what is needed for the current task - I was surprised to find that about 150 data items had faster data retrieval from local MySQL than for non-serialization of a data file.
OTOH is not the best place to store credentials that you need to connect to your database.
Execution conditions
You can set values in runtime . PHP is working.
This removes any requirement for the PHP code to look in a specific location for configuration. OTOH does not scale well for large amounts of data and is difficult to change everywhere at runtime.
On the client
One place that I did not mention for storing configuration data is on the client. Again, network overhead means that it does not scale well for large configuration volumes. And since the end user has control over the data, it must be stored in a format in which any interference can be detected (i.e. with a cryptographic signature), and should not contain any information that is compromised by its disclosure (i.e. reversibly encrypted).
Conversely, it has many advantages for storing confidential information that belongs to the end user - if you do not store it on the server, it cannot be stolen.
Network directories Another interesting place to store configuration information is in DNS / LDAP. This will work for a small number of small pieces of information, but you do not need to adhere to the 1st normal form - consider, for example, SPF ,
The subsystem supports caching, replication and distribution. Therefore, it works well for very large infrastructures.
Version Control Systems
Configuration, such as code, must be versioned and versioned - so getting the configuration directly from your VC system is a viable solution. But often this is associated with significant performance overheads, so caching may be appropriate.