├── bios
└── .gitignore
├── tests
├── Resource
│ └── data
│ │ └── test1.txt
├── Helper
│ └── NumberHelperTest.php
├── Components
│ ├── ChildRegisterTest.php
│ ├── RegisterTest.php
│ ├── FlagsTest.php
│ └── AddressTest.php
└── Machine
│ ├── CpuTest.php
│ └── RamTest.php
├── opt
├── .gitignore
├── install.sh
└── README.md
├── php
├── php.list
├── ext
│ └── xdebug.ini
└── php.ini
├── Makefile
├── .env.example
├── .gitignore
├── src
├── Machine
│ ├── HardDisk.php
│ ├── FloppyDisk.php
│ ├── NullOutputDevice.php
│ ├── OutputDevice.php
│ ├── Disk.php
│ ├── DebugRam.php
│ ├── Ram.php
│ ├── Machine.php
│ └── TtyOutputDevice.php
├── Components
│ ├── Memory.php
│ ├── Event.php
│ ├── AbsoluteAddress.php
│ ├── Register.php
│ ├── ChildRegister.php
│ ├── Flags.php
│ └── Address.php
├── Blueprint
│ ├── AbsoluteAddressInterface.php
│ ├── OutputDeviceInterface.php
│ ├── CpuInterface.php
│ ├── DebugAwareInterface.php
│ ├── RamInterface.php
│ ├── DiskInterface.php
│ ├── ChildRegisterInterface.php
│ ├── MachineInterface.php
│ ├── RegisterInterface.php
│ ├── FlagsInterface.php
│ └── AddressInterface.php
├── Exception
│ ├── NoBiosException.php
│ ├── NoCpuException.php
│ ├── NoRamException.php
│ ├── UnknownTypeException.php
│ ├── NegativeValueException.php
│ ├── NotImplementedException.php
│ └── ValueExceededException.php
├── I8086emu.php
└── Helper
│ ├── DataHelper.php
│ └── NumberHelper.php
├── CHANGELOG-v0.md
├── i8086emu.sublime-project
├── bin
├── coverage.sh
├── phpstan.sh
├── run_test.sh
├── test.sh
├── screen.sh
├── run.sh
├── i8086emu
└── ptty_test.php
├── phpcs.xml
├── .editorconfig
├── .gitlab-ci.yml
├── phpunit.xml
├── LICENSE
├── composer.json
├── Vagrantfile
├── README.md
└── app
└── Command
└── RunCommand.php
/bios/.gitignore:
--------------------------------------------------------------------------------
1 | /bios
2 |
--------------------------------------------------------------------------------
/tests/Resource/data/test1.txt:
--------------------------------------------------------------------------------
1 | ABC
2 |
--------------------------------------------------------------------------------
/opt/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 | !install.sh
4 | !README.md
5 |
--------------------------------------------------------------------------------
/php/php.list:
--------------------------------------------------------------------------------
1 |
2 | deb https://packages.sury.org/php/ stretch main
3 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 |
2 | all: bios/bios
3 |
4 | bios/bios: bios/bios.asm
5 | nasm $<
6 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | IMAGE_NAME="thefox21/i8086emu"
2 | IMAGE_NAME_SHORT="emu"
3 | GITHUB_API_TOKEN=""
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor/
2 | /tmp/
3 | /.idea/
4 | /.vagrant/
5 | .env
6 | /log/
7 | test.php
8 | test.txt
9 |
--------------------------------------------------------------------------------
/src/Machine/HardDisk.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | bin/i8086emu
6 | src
7 |
8 | vendor/
9 |
10 |
--------------------------------------------------------------------------------
/src/Machine/NullOutputDevice.php:
--------------------------------------------------------------------------------
1 | /dev/null || { echo 'ERROR: socat not found in PATH'; exit 1; }
6 |
7 | while [[ ! -e ${TTY_PATH} ]]; do
8 | sleep 0.5
9 | done
10 |
11 | screen ${TTY_PATH}
12 |
13 | status=$?
14 | echo "status: ${status}"
15 |
16 | exit ${status}
17 |
--------------------------------------------------------------------------------
/src/Blueprint/DiskInterface.php:
--------------------------------------------------------------------------------
1 | $char) {
11 | $char = intval($char);
12 | $bits = $index << 3;
13 | $i += $char << $bits;
14 | }
15 | return $i;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Blueprint/MachineInterface.php:
--------------------------------------------------------------------------------
1 | type = $type;
20 | $this->callback = $callback;
21 | }
22 |
23 | /**
24 | * @return int
25 | */
26 | public function getType(): int
27 | {
28 | return $this->type;
29 | }
30 |
31 | public function exec(array $data)
32 | {
33 | $cbf = $this->callback;
34 | $rv = $cbf($data);
35 | return $rv;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Components/AbsoluteAddress.php:
--------------------------------------------------------------------------------
1 | add(new RunCommand());
28 | $application->run();
29 |
--------------------------------------------------------------------------------
/src/Blueprint/AddressInterface.php:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 |
23 | tests
24 |
25 |
26 |
27 |
28 | src
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/tests/Helper/NumberHelperTest.php:
--------------------------------------------------------------------------------
1 | assertEquals($e, $x);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Christian Mayer
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "thefox/i8086emu",
3 | "description": "Intel 8086 CPU Emulator",
4 | "license": "MIT",
5 | "type": "project",
6 | "keywords": [
7 | "Intel",
8 | "8086",
9 | "x86",
10 | "Emulator"
11 | ],
12 | "homepage": "https://fox21.at",
13 | "authors": [
14 | {
15 | "name": "Christian Mayer",
16 | "email": "christian@fox21.at",
17 | "homepage": "https://fox21.at"
18 | }
19 | ],
20 | "require": {
21 | "php": "^7.2",
22 | "symfony/console": "^4.1.0",
23 | "symfony/process": "^4.1.0",
24 | "nesbot/carbon": "^1.32.0"
25 | },
26 | "require-dev": {
27 | "ext-xdebug": "*",
28 | "ext-pcntl": "*",
29 | "phpunit/phpunit": "^7.2.0",
30 | "phpstan/phpstan": "^0.9.0",
31 | "squizlabs/php_codesniffer": "^3.3.0"
32 | },
33 | "autoload": {
34 | "psr-4": {
35 | "TheFox\\I8086emu\\": "src",
36 | "App\\": "app"
37 | }
38 | },
39 | "autoload-dev": {
40 | "psr-4": {
41 | "TheFox\\I8086emu\\Test\\": "tests"
42 | }
43 | },
44 | "bin": [
45 | "bin/i8086emu"
46 | ]
47 | }
48 |
--------------------------------------------------------------------------------
/tests/Components/ChildRegisterTest.php:
--------------------------------------------------------------------------------
1 | setData([1, 2]);
16 |
17 | $i = $parent->toInt();
18 | $this->assertEquals(1, $i);
19 | }
20 |
21 | public function addDataProvider()
22 | {
23 | $data = [
24 | [0x1234, 1, 0x1235, 0],
25 | [0x12ff, 2, 0x1201, 0],
26 |
27 | [0x1234, 1, 0x1334, 1],
28 | [0x12ff, 2, 0x14ff, 1],
29 | [0xff34, 2, 0x0134, 1],
30 | ];
31 | return $data;
32 | }
33 |
34 | /**
35 | * @dataProvider addDataProvider
36 | */
37 | public function testAdd(int $bi, int $add, int $expected, bool $isHigh)
38 | {
39 | $parent = new Register(2, $bi, 'PR');
40 | $child = new ChildRegister($parent, $isHigh, 'CR');
41 | $ni1 = $child->add($add);
42 |
43 | $ni2 = $parent->toInt();
44 | $this->assertEquals($expected, $ni1);
45 | $this->assertEquals($expected, $ni2);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Machine/Disk.php:
--------------------------------------------------------------------------------
1 | name = $name;
24 | }
25 |
26 | public function __toString()
27 | {
28 | if ($this->name) {
29 | return sprintf('DISK[%s]', $this->name);
30 | }
31 | return 'DISK';
32 | }
33 |
34 | public function setName(string $name): void
35 | {
36 | $this->name = $name;
37 | }
38 |
39 | public function setFilePath(string $sourceFilePath): void
40 | {
41 | $this->filePath = $sourceFilePath;
42 | }
43 |
44 | public function getContent(?int $length = null): \SplFixedArray
45 | {
46 | $content = file_get_contents($this->filePath, false, null, 0, $length);
47 | $data = str_split($content);
48 | unset($content);
49 | $data = array_map('ord', $data);
50 | $data = \SplFixedArray::fromArray($data);
51 | return $data;
52 | }
53 |
54 | public function getFd()
55 | {
56 | if (null === $this->fd) {
57 | $this->fd = fopen($this->filePath, 'a+');
58 | }
59 | return $this->fd;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Vagrantfile:
--------------------------------------------------------------------------------
1 | # -*- mode: ruby -*-
2 | # vi: set ft=ruby :
3 |
4 | Vagrant.configure("2") do |config|
5 | config.vm.box = "generic/debian9"
6 | config.vm.box_check_update = false
7 |
8 | #config.vm.network "forwarded_port", guest: 3000, host: 3001
9 |
10 | config.vm.hostname = 'i8086emu'
11 | # config.vm.network "private_network", ip: "192.168.33.10"
12 | config.vm.synced_folder ".", "/app"
13 |
14 | config.vm.provider "virtualbox" do |vb|
15 | vb.gui = false
16 | vb.memory = 1024
17 | end
18 |
19 | config.vm.provision "shell" do |s|
20 | s.env = {
21 | 'WORKING_DIR' => '/app',
22 | 'PHP_VERSION' => '7.2',
23 | }
24 | s.inline = <<-SHELL
25 | echo "cd ${WORKING_DIR}" >> /home/vagrant/.bashrc
26 | echo "export PHP_IDE_CONFIG='serverName=vagrant'" >> /home/vagrant/.bashrc
27 |
28 | apt-get install -y apt-transport-https ca-certificates
29 |
30 | cp /app/php/php.list /etc/apt/sources.list.d/php.list
31 | [[ ! -f /etc/apt/trusted.gpg.d/php.gpg ]] && wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
32 |
33 | apt-get update -yqq
34 | apt-get upgrade -y
35 | apt-get install -y man rsync ack git gawk htop tig net-tools zlib1g-dev nasm socat php${PHP_VERSION}-dev php${PHP_VERSION}-cli php${PHP_VERSION}-zip php${PHP_VERSION}-mbstring composer
36 |
37 | netstat -rn | grep "^0.0.0.0 " | cut -d " " -f10 > /tmp/host_ip.txt
38 | host_ip=$(cat /tmp/host_ip.txt)
39 |
40 | cp ${WORKING_DIR}/php/php.ini /etc/php/${PHP_VERSION}/cli/php.ini
41 |
42 | pecl install xdebug
43 | sed -e "s/@HOST_IP@/$host_ip/g" ${WORKING_DIR}/php/ext/xdebug.ini > /etc/php/${PHP_VERSION}/cli/conf.d/20-xdebug.ini
44 |
45 | echo 'done'
46 | SHELL
47 | end
48 | end
49 |
--------------------------------------------------------------------------------
/src/Components/Register.php:
--------------------------------------------------------------------------------
1 | setName($name);
23 | }
24 |
25 | public function __toString(): string
26 | {
27 | $format = sprintf('%s[%%0%dx]', $this->getName(), $this->getSize() << 1);
28 | $s = sprintf($format, $this->toInt());
29 | return $s;
30 | }
31 |
32 | public function setName(?string $name): void
33 | {
34 | $this->name = $name;
35 | }
36 |
37 | public function getName(): string
38 | {
39 | return $this->name;
40 | }
41 |
42 | public function getLowRegister(): Register
43 | {
44 | // Replace "AX" with "AL".
45 | $name = str_replace('X', 'L', $this->getName());
46 |
47 | $child = new ChildRegister($this, false, $name);
48 | return $child;
49 | }
50 |
51 | public function getHighRegister(): Register
52 | {
53 | // Replace "AX" with "AH".
54 | $name = str_replace('X', 'H', $this->getName());
55 |
56 | $child = new ChildRegister($this, true, $name);
57 | return $child;
58 | }
59 |
60 | public function getChildRegister(bool $isHigh = false): Register
61 | {
62 | if ($isHigh) {
63 | return $this->getHighRegister();
64 | }
65 | return $this->getLowRegister();
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/tests/Components/RegisterTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(1, $register2->toInt());
21 | $this->assertEquals(2, $register3->toInt());
22 | $data2 = $register2->getData()->toArray();
23 | $data3 = $register3->getData()->toArray();
24 | $this->assertEquals([1], $data2);
25 | $this->assertEquals([2], $data3);
26 |
27 | // Set Low child.
28 | $register2->setData(0x105);
29 |
30 | $this->assertEquals(0x205, $register1->toInt());
31 | $this->assertEquals(5, $register2->toInt());
32 | $this->assertEquals(2, $register3->toInt());
33 | $data2 = $register2->getData()->toArray();
34 | $data3 = $register3->getData()->toArray();
35 | $this->assertEquals([5], $data2);
36 | $this->assertEquals([2], $data3);
37 |
38 | // Set High child.
39 | $register3->setData(0x104);
40 |
41 | $this->assertEquals(0x405, $register1->toInt());
42 | $this->assertEquals(5, $register2->toInt());
43 | $this->assertEquals(4, $register3->toInt());
44 | $data2 = $register2->getData()->toArray();
45 | $data3 = $register3->getData()->toArray();
46 | $this->assertEquals([5], $data2);
47 | $this->assertEquals([4], $data3);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/tests/Machine/CpuTest.php:
--------------------------------------------------------------------------------
1 | assertEquals($expectedId, $id1);
36 |
37 | $id2 = $iReg4bit >> 1 & 1;
38 | $this->assertEquals($expectedId, $id2);
39 | }
40 |
41 | /**
42 | * @return array
43 | */
44 | public function iRegDataProvider()
45 | {
46 | $data = [
47 | [0, 0],
48 | [9, 1],
49 | [0x38, 7],
50 | [0x39, 7],
51 | [0xFFFF, 7],
52 | ];
53 | return $data;
54 | }
55 |
56 | /**
57 | * @dataProvider iRegDataProvider
58 | * @param int $iData0
59 | * @param int $expected
60 | */
61 | public function testIreg(int $iData0, int $expected)
62 | {
63 | $iReg1 = $iData0 / 8 & 7;
64 | $this->assertEquals($expected, $iReg1);
65 |
66 | $iReg2 = $iData0 >> 3 & 7;
67 | $this->assertEquals($expected, $iReg2);
68 |
69 | $iReg3 = ($iData0 & 0x38) >> 3; // xx111xxx
70 | $this->assertEquals($expected, $iReg3);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/Machine/DebugRam.php:
--------------------------------------------------------------------------------
1 | events = [];
24 | }
25 |
26 | public function write($data, int $offset, int $length): void
27 | {
28 | $eventData = [
29 | 'data' => $data,
30 | 'offset' => $offset,
31 | 'length' => $length,
32 | ];
33 | $this->execEvents(self::EVENT_WRITE_PRE, $eventData);
34 |
35 | parent::write($data, $offset, $length);
36 |
37 | $this->execEvents(self::EVENT_WRITE_POST, $eventData);
38 | }
39 |
40 | public function read(int $offset, int $length): \SplFixedArray
41 | {
42 | $eventData = [
43 | 'offset' => $offset,
44 | 'length' => $length,
45 | ];
46 | $this->execEvents(self::EVENT_READ_PRE,$eventData);
47 |
48 | $rv = parent::read($offset, $length);
49 |
50 | $this->execEvents(self::EVENT_READ_POST,$eventData);
51 |
52 | return $rv;
53 | }
54 |
55 | public function addEvent(Event $event)
56 | {
57 | $type = $event->getType();
58 | if (array_key_exists($type, $this->events)) {
59 | $this->events[$type][] = $event;
60 | } else {
61 | $this->events[$type] = [$event];
62 | }
63 | }
64 |
65 | private function execEvents(int $type, array $data = [])
66 | {
67 | if (!array_key_exists($type, $this->events)) {
68 | return;
69 | }
70 |
71 | /** @var Event[] $events */
72 | $events = $this->events[$type];
73 | foreach ($events as $event) {
74 | $event->exec($data);
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/Machine/Ram.php:
--------------------------------------------------------------------------------
1 | size = $size;
27 | $this->data = new \SplFixedArray($this->size);
28 | }
29 |
30 | /**
31 | * @param iterable|int $data
32 | * @param int $offset
33 | * @param int $length
34 | */
35 | public function write($data, int $offset, int $length): void
36 | {
37 | $pos = $offset;
38 | $maxPos = $pos + $length;
39 |
40 | if (is_iterable($data)) {
41 | foreach ($data as $c) {
42 | $this->data[$pos] = intval($c) & 0xFF;
43 |
44 | ++$pos;
45 | if ($pos === $maxPos) {
46 | break;
47 | }
48 | }
49 | } elseif (is_numeric($data)) {
50 | for (; $data > 0 && $pos < $maxPos; ++$pos, $data >>= 8) {
51 | $this->data[$pos] = $data & 0xFF;
52 | }
53 | } elseif (is_string($data)) {
54 | $data = str_split($data);
55 | $data = array_map('ord', $data);
56 | $this->write($data, $offset, $length);
57 | } else {
58 | throw new UnknownTypeException();
59 | }
60 | }
61 |
62 | /**
63 | * @param int $offset
64 | * @param int $length
65 | * @return \SplFixedArray
66 | */
67 | public function read(int $offset, int $length): \SplFixedArray
68 | {
69 | $data = new \SplFixedArray($length);
70 | $maxPos = $offset + $length;
71 | for ($pos = $offset, $i = 0; $pos < $maxPos; ++$pos, ++$i) {
72 | $data[$i] = $this->data[$pos];
73 | }
74 |
75 | return $data;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/tests/Components/FlagsTest.php:
--------------------------------------------------------------------------------
1 | assertFalse($flags->get(0)); // CF
16 |
17 | // Set 1
18 | $flags->set(0, true);
19 | $this->assertTrue($flags->get(0));
20 | $this->assertTrue($flags->getByName('CF'));
21 | $this->assertTrue($flags->get(1)); // Default true
22 | $this->assertFalse($flags->get(3)); // Default false
23 |
24 | // Set 2
25 | $flags->setByName('CF', false);
26 | $this->assertFalse($flags->get(0));
27 |
28 | // Name
29 | $name = $flags->getName(0);
30 | $this->assertEquals('CF', $name);
31 | }
32 |
33 | /**
34 | * @expectedException \TypeError
35 | */
36 | public function testException()
37 | {
38 | $flags = new Flags();
39 | $flags->get('INVALID');
40 | }
41 |
42 | public function testSetIntData()
43 | {
44 | $flags = new Flags();
45 | $flags->setIntData(0xFFAA); // 1111 1111 1010 1010
46 |
47 | $this->assertFalse($flags->get(0));
48 | $this->assertTrue($flags->get(1));
49 | $this->assertFalse($flags->get(2));
50 | $this->assertTrue($flags->get(3));
51 |
52 | $this->assertFalse($flags->get(4));
53 | $this->assertTrue($flags->get(5));
54 | $this->assertFalse($flags->get(6));
55 | $this->assertTrue($flags->get(7));
56 |
57 | $this->assertTrue($flags->get(8));
58 | $this->assertTrue($flags->get(9));
59 | $this->assertTrue($flags->get(10));
60 | $this->assertTrue($flags->get(11));
61 |
62 | $this->assertFalse($flags->get(12));
63 | $this->assertTrue($flags->get(13));
64 | $this->assertTrue($flags->get(14));
65 | $this->assertTrue($flags->get(15));
66 |
67 | $data = $flags->getData()->toArray();
68 | $this->assertEquals([0xAA, 0xEF], $data);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/tests/Machine/RamTest.php:
--------------------------------------------------------------------------------
1 | ram = $this->getNewRam();
18 | }
19 |
20 | private function getNewRam(int $size = 0x10000)
21 | {
22 | return new Ram($size);
23 | }
24 |
25 | public function testWriteReadArray()
26 | {
27 | // Write
28 | $this->ram->write([1, 2, 3], 0,3);
29 |
30 | $data = $this->ram->read(0, 1)->toArray();
31 | $this->assertEquals([1], $data);
32 |
33 | $data = $this->ram->read(0, 2)->toArray();
34 | $this->assertEquals([1, 2], $data);
35 |
36 | $data = $this->ram->read(0, 3)->toArray();
37 | $this->assertEquals([1, 2, 3], $data);
38 |
39 | // Read Offset > 0
40 | $data = $this->ram->read(1, 1)->toArray();
41 | $this->assertEquals([2], $data);
42 |
43 | $data = $this->ram->read(1, 2)->toArray();
44 | $this->assertEquals([2, 3], $data);
45 |
46 | // Read untouched RAM Addr.
47 | $data = $this->ram->read(0, 4)->toArray();
48 | $this->assertEquals([1, 2, 3, 0], $data);
49 |
50 | $data = $this->ram->read(2, 2)->toArray();
51 | $this->assertEquals([3, 0], $data);
52 |
53 | // Write Offset > 0
54 | $this->ram->write([4, 5, 6, 7], 5,4);
55 |
56 | $data = $this->ram->read(2, 5)->toArray();
57 | $this->assertEquals([3, 0, 0, 4, 5], $data);
58 |
59 | // Continue writing
60 | $this->ram->write([8, 9, 10], 9,3);
61 |
62 | $data = $this->ram->read(0, 12)->toArray();
63 | $this->assertEquals([1, 2, 3, 0, 0, 4, 5, 6, 7, 8, 9, 10], $data);
64 | }
65 |
66 | public function testWriteReadInt()
67 | {
68 | // Write
69 | $this->ram->write(0x42, 0,1);
70 | $this->ram->write(0x454443, 1,3);
71 |
72 | // Read
73 | $data = $this->ram->read(0, 4)->toArray();
74 | $this->assertEquals([0x42,0x43,0x44,0x45], $data);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Intel 8086 CPU Emulator
2 |
3 | An Intel 8086 CPU Emulator written in pure PHP.
4 |
5 | ## Project Outlines
6 |
7 | The project outlines as described in my blog post about [Open Source Software Collaboration](https://blog.fox21.at/2019/02/21/open-source-software-collaboration.html).
8 |
9 | - The main purpose of this software is to emulate the Intel 8086 CPU using pure PHP.
10 | - The features should not go beyond Intel's features and functions. So the features of this software are limited to those of the Intel 8086 CPU.
11 | - This list is open. Feel free to request features.
12 |
13 | ## Compile the BIOS
14 |
15 | Run `make bios/bios`.
16 |
17 | ## TTY
18 |
19 | In order to have a TTY for the in- and output you can specify `--tty `. This will start a `socat` subprocess to create an interface between PHP and TTY. The TTY then can be accessed using `screen`.
20 |
21 | Optional, to use a different installation path for the `socat` binary you can specify `--socat `.
22 |
23 | 1. Install `socat`.
24 | 2. Open a shell and run `./bin/screen.sh`.
25 | 3. Open another shell and run `./bin/run.sh`.
26 |
27 | ## Terms
28 |
29 | - `Byte` - 8 bit, one single character.
30 | - `Word` - 16 bit, or 2 Byte.
31 |
32 | ## 8086 Resources
33 |
34 | - [Wikipedia: Intel 8086](https://en.wikipedia.org/wiki/Intel_8086)
35 | - [Wikipedia: Processor Register](https://en.wikipedia.org/wiki/Processor_register)
36 | - [Wikipedia: FLAGS Register](https://en.wikipedia.org/wiki/FLAGS_register)
37 | - [Wikipedia: Parity Flag](https://en.wikipedia.org/wiki/Parity_flag)
38 | - [Wikipedia: Word](https://en.wikipedia.org/wiki/Word_(computer_architecture))
39 | - [8086 opcodes](http://www.mlsite.net/8086/)
40 | - [StackExchange: Emulate an Intel 8086 CPU](https://codegolf.stackexchange.com/questions/4732/emulate-an-intel-8086-cpu)
41 | - [x86 Registers](http://www.eecg.toronto.edu/~amza/www.mindsec.com/files/x86regs.html)
42 | - [Encoding x86 Instructions](https://www-user.tu-chemnitz.de/~heha/viewchm.php/hs/x86.chm/x86.htm)
43 | - [Encoding x86 Instruction Operands, MOD-REG-R/M Byte](http://www.c-jump.com/CIS77/CPU/x86/X77_0060_mod_reg_r_m_byte.htm)
44 | - [X86 Assembly/X86 Architecture](https://en.wikibooks.org/wiki/X86_Assembly/X86_Architecture)
45 | - [X86-64 Instruction Encoding](http://wiki.osdev.org/X86-64_Instruction_Encoding)
46 | - [OUT -- Output to Port](https://pdos.csail.mit.edu/6.828/2010/readings/i386/OUT.htm)
47 | - [MDA, CGA, HGC, EGA, VGA, SVGA, TIGA](https://www.tu-chemnitz.de/informatik/RA/news/stack/kompendium/vortraege_98/grafik/adaptertypen.html) (German)
48 | - [8086/88 Assembler Befehlsreferenz](http://www.i8086.de/asm/8086-88-asm.html) (German)
49 | - [X86 Opcode and Instruction Reference](http://ref.x86asm.net/coder32.html)
50 | - [Understanding Intel Instruction Sizes](https://www.swansontec.com/sintel.html)
51 |
52 | ## More Resources
53 |
54 | - [How To Write a Computer Emulator](https://fms.komkon.org/EMUL8/HOWTO.html)
55 |
--------------------------------------------------------------------------------
/app/Command/RunCommand.php:
--------------------------------------------------------------------------------
1 | setName('run');
18 |
19 | $this->addOption('bios', 'b', InputOption::VALUE_REQUIRED, 'Path to bios.');
20 | $this->addOption('floppy', 'f', InputOption::VALUE_REQUIRED, 'Path to floppydisk-file.');
21 | $this->addOption('harddisk', 'd', InputOption::VALUE_REQUIRED, 'Path to harddisk-file.');
22 | $this->addOption('tty', 't', InputOption::VALUE_REQUIRED, 'Path to Screen TTY.');
23 | $this->addOption('socat', null, InputOption::VALUE_REQUIRED, 'Path to the socat binary.');
24 | }
25 |
26 | /**
27 | * @param InputInterface $input
28 | * @param OutputInterface $output
29 | * @return int
30 | */
31 | protected function execute(InputInterface $input, OutputInterface $output): int
32 | {
33 | if ($input->hasOption('bios')) {
34 | $biosFilePath = $input->getOption('bios');
35 | }
36 | if ($input->hasOption('floppy')) {
37 | $floppyFilePath = $input->getOption('floppy');
38 | }
39 | //if ($input->hasOption('harddisk')) {
40 | // $harddiskFilePath = $input->getOption('harddisk');
41 | //}
42 | if ($input->hasOption('tty')) {
43 | $ttyFilePath = $input->getOption('tty');
44 | }
45 | if ($input->hasOption('socat')) {
46 | $socatFilePath = $input->getOption('socat');
47 | }
48 |
49 | $machine = new Machine();
50 | $machine->setOutput($output);
51 |
52 | if (isset($biosFilePath)) {
53 | $biosDisk = new Disk('bios');
54 | $biosDisk->setFilePath($biosFilePath);
55 |
56 | $machine->setBios($biosDisk);
57 | }
58 | if (isset($floppyFilePath)) {
59 | $floppyDisk = new Disk('floppy');
60 | $floppyDisk->setFilePath($floppyFilePath);
61 |
62 | $machine->setFloppyDisk($floppyDisk);
63 | }
64 | if (isset($harddiskFilePath)) {
65 | $hardDisk = new Disk('hdd');
66 | $hardDisk->setFilePath($harddiskFilePath);
67 |
68 | $machine->setHardDisk($hardDisk);
69 | }
70 | if (isset($ttyFilePath)) {
71 | $tty = new TtyOutputDevice();
72 | $tty->setTtyFilePath($ttyFilePath);
73 |
74 | if (isset($socatFilePath) && $socatFilePath) {
75 | $tty->setSocatFilePath($socatFilePath);
76 | }
77 |
78 | $machine->setTty($tty);
79 | }
80 |
81 | $machine->run();
82 |
83 | return 0;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/bin/ptty_test.php:
--------------------------------------------------------------------------------
1 | readable\n");
36 | // }
37 | // foreach ($writeHandles as $writeableHandle) {
38 | // //printf(" -> writeable\n");
39 | // fwrite($writeableHandle, date('Y-m-d H:i:s') . "\r\n");
40 | // }
41 | // } else {
42 | // printf("no changed streams\n");
43 | // }
44 | // printf("\n");
45 | //}
46 | //
47 | //printf("close\n");
48 | //fclose($fh);
49 | #unlink($pipePath);
50 |
51 | // $cmd = 'socat PTY,link=/dev/csTTY1,rawer,wait-slave STDIO';
52 | $cmd = 'socat PTY,link=/tmp/csTTY1,rawer,wait-slave STDIO';
53 | $fds = [
54 | 0 => ['pipe', 'rb'], // STDIN
55 | 1 => ['pipe', 'wb'], // STDOUT
56 | 2 => ['file', '/tmp/error.log', 'wb'], // STDERR
57 | ];
58 | //$env=[];
59 | $pipes = [];
60 |
61 | $proc = proc_open($cmd, $fds, $pipes);
62 | //fwrite($pipes[2], "das ist ein test\n");
63 |
64 | if (!is_resource($proc)) {
65 | printf("ERROR: no res\n");
66 | exit(1);
67 | }
68 |
69 | for ($i = 0; $i < 60; ++$i) {
70 | sleep(1);
71 |
72 | printf("loop %d\n", $i);
73 |
74 | fwrite($pipes[0], date('Y-m-d H:i:s') . "\r\n");
75 |
76 | $readHandles = [$pipes[1]];
77 | $writeHandles = [];
78 | $exceptHandles = [];
79 | $handlesChanged = stream_select($readHandles, $writeHandles, $exceptHandles, 0);
80 | printf("streams: %d\n", $handlesChanged);
81 |
82 | if ($handlesChanged) {
83 | printf("changed streams: %d %d\n", count($readHandles), count($writeHandles));
84 |
85 | foreach ($readHandles as $readableHandle) {
86 | printf(" -> readable\n");
87 | //$data=stream_socket_recvfrom($readableHandle, 2048);
88 | $maxLen = 2048;
89 | $data = fread($readableHandle, 2048);
90 |
91 | for ($i = 0; $i < $maxLen; ++$i) {
92 | if (!isset($data[$i])) {
93 | printf(" -> break\n");
94 | break;
95 | }
96 | $c = $data[$i];
97 | printf(" -> 0x%x\n", ord($c));
98 | }
99 | }
100 | }
101 | }
102 |
103 | foreach ($pipes as $pipe) {
104 | fclose($pipe);
105 | }
106 | proc_close($proc);
107 |
108 | printf("end\n");
109 |
--------------------------------------------------------------------------------
/src/Components/ChildRegister.php:
--------------------------------------------------------------------------------
1 | isParentHigh = $isParentHigh;
22 | $size = $parent->getHalfSize(); // We take it from parent.
23 | $data = null;
24 |
25 | parent::__construct($size, $data, $name);
26 |
27 | $this->parent = $parent;
28 | }
29 |
30 | public function setParent(Register $parent): void
31 | {
32 | $this->parent = $parent;
33 | $this->setSize($this->getHalfSize());
34 | }
35 |
36 | /**
37 | * @return bool
38 | */
39 | public function isParentHigh(): bool
40 | {
41 | return $this->isParentHigh;
42 | }
43 |
44 | /**
45 | * @param bool $isParentHigh
46 | */
47 | public function setIsParentHigh(bool $isParentHigh = true): void
48 | {
49 | $this->isParentHigh = $isParentHigh;
50 | }
51 |
52 | public function setData($data, bool $reset = true): void
53 | {
54 | if (null === $this->parent) {
55 | // Skip setData while __construct().
56 | return;
57 | }
58 |
59 | if (is_iterable($data)) {
60 | $data = $data[0];
61 | }
62 | //if (!is_numeric($data)) {
63 | // throw new \RuntimeException('Only numeric supported.');
64 | //}
65 | $data = intval($data);
66 |
67 | $data &= 0xFF;
68 | if ($this->isParentHigh) {
69 | $low = $this->parent->getLowInt();
70 | $bits = $this->parent->getHalfBits();
71 | $high = $data << $bits;
72 | } else {
73 | $low = $data;
74 | $high = $this->parent->getEffectiveHighInt();
75 | }
76 | $newData = $high | $low;
77 |
78 | $this->parent->setData($newData);
79 | }
80 |
81 | /**
82 | * @return \SplFixedArray
83 | */
84 | public function getData(): \SplFixedArray
85 | {
86 | $halfSize = $this->getHalfSize();
87 | $dataArray = $this->parent->getData()->toArray();
88 |
89 | if ($this->isParentHigh) {
90 | $data = array_slice($dataArray, $halfSize);
91 | } else {
92 | $data = array_slice($dataArray, 0, $halfSize);
93 | }
94 |
95 | return \SplFixedArray::fromArray($data);
96 | }
97 |
98 | /**
99 | * @return int
100 | */
101 | public function toInt(): int
102 | {
103 | if ($this->isParentHigh) {
104 | return $this->parent->getHighInt();
105 | }
106 |
107 | return $this->parent->getLowInt();
108 | }
109 |
110 | public function add(int $i): int
111 | {
112 | $endVal = $this->toInt() + $i;
113 |
114 | if ($this->isParentHigh) {
115 | return $this->parent->setHighInt($endVal);
116 | }
117 |
118 | return $this->parent->setLowInt($endVal);
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/tests/Components/AddressTest.php:
--------------------------------------------------------------------------------
1 | setSize($size);
60 | $address->setData($data);
61 | if (null !== $add) {
62 | $addRes = $address->add($add);
63 | }
64 |
65 | $this->assertEquals($expectedInt, $address->toInt());
66 | if (isset($addRes)) {
67 | $this->assertEquals($expectedInt, $addRes);
68 | }
69 |
70 | if (null !== $expectedLowInt) {
71 | $this->assertEquals($expectedLowInt, $address->getLowInt());
72 | }
73 | if (null !== $expectedHighInt) {
74 | $this->assertEquals($expectedHighInt, $address->getHighInt());
75 | }
76 | if (null !== $expectedEffectiveHighInt) {
77 | $this->assertEquals($expectedEffectiveHighInt, $address->getEffectiveHighInt());
78 | }
79 | }
80 |
81 | public function testSetLowHighBit16()
82 | {
83 | $address = new Address();
84 | $address->setSize(2);
85 | $address->setData([1, 2]);
86 | $data = $address->getData()->toArray();
87 | $this->assertEquals([1, 2], $data);
88 |
89 | $address->setLowInt(3);
90 | $data = $address->getData()->toArray();
91 | $this->assertEquals([3, 2], $data);
92 |
93 | $address->setHighInt(4);
94 | $data = $address->getData()->toArray();
95 | $this->assertEquals([3, 4], $data);
96 |
97 | $address->setLowInt(0x1234);
98 | $data = $address->getData()->toArray();
99 | $this->assertEquals([0x34, 4], $data);
100 | }
101 |
102 | public function testSetLowHighBit48()
103 | {
104 | $address = new Address();
105 | $address->setSize(6);
106 | $address->setData([0, 1, 2, 3, 4, 5]);
107 | $data = $address->getData()->toArray();
108 | $this->assertEquals([0, 1, 2, 3, 4, 5], $data);
109 |
110 | $address->setLowInt(3);
111 | $data = $address->getData()->toArray();
112 | $this->assertEquals([3, 0, 0, 3, 4, 5], $data);
113 |
114 | $address->setLowInt(0x123456);
115 | $data = $address->getData()->toArray();
116 | $this->assertEquals([0x56, 0x34, 0x12, 3, 4, 5], $data);
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/src/Machine/Machine.php:
--------------------------------------------------------------------------------
1 | ram = new Ram(0x00100000); // 1 MB
76 | // $this->ram = new DebugRam(0x00100000); // 1 MB
77 | $this->cpu = new Cpu($this);
78 | $this->tty = new NullOutputDevice();
79 |
80 | $this->output = new NullOutput();
81 | }
82 |
83 | public function run(): void
84 | {
85 | if (!$this->ram || !$this->ram instanceof RamInterface) {
86 | throw new NoRamException();
87 | }
88 |
89 | if (!$this->cpu || !$this->cpu instanceof CpuInterface) {
90 | throw new NoCpuException();
91 | }
92 |
93 | if (!$this->bios) {
94 | throw new NoBiosException();
95 | }
96 |
97 | // Load BIOS into RAM.
98 | $biosOffset = (0xF000 << 4) + 0x0100;
99 | $biosLen = 0xFF00;
100 | $biosEnd = $biosOffset + $biosLen;
101 | $this->output->writeln(sprintf('[MACHINE] bios start %08x', $biosOffset));
102 | $this->output->writeln(sprintf('[MACHINE] bios end %08x', $biosEnd));
103 | $data = $this->bios->getContent($biosLen);
104 | $this->ram->write($data, $biosOffset, $biosLen);
105 |
106 | // Setup CPU.
107 | $this->output->writeln('[MACHINE] set ram');
108 | $this->cpu->setRam($this->ram);
109 |
110 | // Setup TTY.
111 | $this->output->writeln('[MACHINE] set TTY');
112 | $this->cpu->setTty($this->tty);
113 |
114 | // Run the CPU.
115 | $this->cpu->run();
116 | }
117 |
118 | /**
119 | * @param Disk $bios
120 | */
121 | public function setBios(Disk $bios): void
122 | {
123 | $this->bios = $bios;
124 | }
125 |
126 | /**
127 | * @param Disk $floppyDisk
128 | */
129 | public function setFloppyDisk(Disk $floppyDisk): void
130 | {
131 | $this->floppyDisk = $floppyDisk;
132 | }
133 |
134 | /**
135 | * @param Disk $hardDisk
136 | */
137 | public function setHardDisk(Disk $hardDisk): void
138 | {
139 | $this->hardDisk = $hardDisk;
140 | }
141 |
142 | public function setTty(OutputDeviceInterface $tty): void
143 | {
144 | $this->tty = $tty;
145 | }
146 |
147 | /**
148 | * @return OutputDeviceInterface|null
149 | */
150 | public function getTty(): ?OutputDeviceInterface
151 | {
152 | return $this->tty;
153 | }
154 |
155 | /**
156 | * @param OutputInterface $output
157 | */
158 | public function setOutput(OutputInterface $output): void
159 | {
160 | $this->output = $output;
161 |
162 | $this->cpu->setOutput($this->output);
163 | }
164 |
165 | public function getDiskByNum(int $diskId): DiskInterface
166 | {
167 | switch ($diskId) {
168 | case 2:
169 | return $this->hardDisk;
170 | case 1:
171 | return $this->floppyDisk;
172 | case 0:
173 | return $this->bios;
174 | }
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/src/Machine/TtyOutputDevice.php:
--------------------------------------------------------------------------------
1 | socatFilePath = 'socat';
59 | $this->fileHandles = [
60 | 0 => ['pipe', 'rb'], // STDIN
61 | 1 => ['pipe', 'wb'], // STDOUT
62 | 2 => ['file', '/tmp/error.log', 'wb'], // STDERR
63 | ];
64 | $this->pipes = [];
65 | $this->isRunning = false;
66 | $this->inputBuffer = [];
67 | }
68 |
69 | public function __destruct()
70 | {
71 | if ($this->isRunning && $this->process) {
72 | $process = $this->process;
73 |
74 | $this->isRunning = false;
75 | $this->process = null;
76 |
77 | proc_terminate($process, SIGKILL);
78 | }
79 | }
80 |
81 | /**
82 | * @param string $ttyFilePath
83 | */
84 | public function setTtyFilePath(string $ttyFilePath): void
85 | {
86 | $this->ttyFilePath = $ttyFilePath;
87 | }
88 |
89 | /**
90 | * @param string $socatFilePath
91 | */
92 | public function setSocatFilePath(string $socatFilePath): void
93 | {
94 | $this->socatFilePath = $socatFilePath;
95 | }
96 |
97 | private function start()
98 | {
99 | if (!$this->isRunning) {
100 | $this->process = proc_open($this->cmd, $this->fileHandles, $this->pipes);
101 | $this->isRunning = true;
102 | }
103 | }
104 |
105 | public function init(): void
106 | {
107 | if (null === $this->ttyFilePath) {
108 | return;
109 | }
110 |
111 | $this->cmd = sprintf('%s PTY,link=%s,rawer,wait-slave STDIO', $this->socatFilePath, $this->ttyFilePath);
112 | $this->pipes = [];
113 | $this->start();
114 | }
115 |
116 | public function run(): void
117 | {
118 | $this->process();
119 | }
120 |
121 | private function process(): void
122 | {
123 | // Write
124 | $this->write();
125 |
126 | // Read
127 | $this->read();
128 | }
129 |
130 | private function write()
131 | {
132 | if (!$this->outputBuffer) {
133 | return;
134 | }
135 |
136 | $tmpOut = $this->outputBuffer;
137 | $this->outputBuffer = null;
138 | fwrite($this->pipes[0], $tmpOut);
139 | fflush($this->pipes[0]);
140 | }
141 |
142 | private function read()
143 | {
144 | $readHandles = [$this->pipes[1]];
145 | $writeHandles = [];
146 | $exceptHandles = [];
147 | $handlesChanged = stream_select($readHandles, $writeHandles, $exceptHandles, 0);
148 | // printf("streams: %d\n", $handlesChanged);
149 |
150 | if (!$handlesChanged) {
151 | return;
152 | }
153 |
154 | // printf("changed streams: %d %d\n", count($readHandles), count($writeHandles));
155 |
156 | foreach ($readHandles as $readableHandle) {
157 | // printf(" -> readable\n");
158 | //$data=stream_socket_recvfrom($readableHandle, 2048);
159 | $maxLen = 2048;
160 | $data = fread($readableHandle, 2048);
161 |
162 | for ($i = 0; $i < $maxLen; ++$i) {
163 | if (!isset($data[$i])) {
164 | // printf(" -> break\n");
165 | break;
166 | }
167 | $c = $data[$i];
168 | // printf(" -> 0x%x\n", ord($c));
169 | $this->inputBuffer[] = ord($c);
170 | }
171 | }
172 | }
173 |
174 | public function putChar(string $char): void
175 | {
176 | $this->outputBuffer .= $char;
177 | }
178 |
179 | public function getChar(): ?int
180 | {
181 | $char = array_shift($this->inputBuffer);
182 | return $char;
183 | }
184 | }
185 |
--------------------------------------------------------------------------------
/src/Components/Flags.php:
--------------------------------------------------------------------------------
1 | 0, // carry flag
23 | 'R1' => 1, // 1 reserved
24 | 'PF' => 2, // parity flag
25 | 'R3' => 3, // 3 reserved
26 |
27 | 'AF' => 4, // auxiliary carry flag
28 | 'R5' => 5, // 5 reserved
29 | 'ZF' => 6, // zero flag
30 | 'SF' => 7, // sign flag
31 |
32 | 'TF' => 8, // trap flag
33 | 'IF' => 9, // interrupt enable flag
34 | 'DF' => 10, // direction flag
35 | 'OF' => 11, // overflow flag
36 |
37 | 'XF' => 12, // 12 reserved
38 | 'R13' => 13, // 13 reserved
39 | 'R14' => 14, // 14 reserved
40 | 'R15' => 15, // 15 reserved
41 | ];
42 |
43 | /**
44 | * @var \SplFixedArray
45 | */
46 | private $data;
47 |
48 | /**
49 | * @var array
50 | */
51 | private $flippedNames;
52 |
53 | public function __construct()
54 | {
55 | /**
56 | * @link https://en.wikipedia.org/wiki/FLAGS_register
57 | * Hint for reserved FLAGs 1 and 12 to 15:
58 | * Regarding to Wikipedia these flags should always be `1`.
59 | * But since we are using FLAG 12 as a always-zero FLAG we
60 | * have to set FLAG 12 to `0` here.
61 | *
62 | * Always-Zero FLAG is used to calculate JMP.
63 | */
64 | $this->data = \SplFixedArray::fromArray([
65 | false, // carry flag
66 | true, // 1 reserved
67 | false, // parity flag
68 | false, // 3 reserved
69 | false, // auxiliary carry flag
70 | false, // 5 reserved
71 | false, // zero flag
72 | false, // sign flag
73 | false, // trap flag
74 | false, // interrupt enable flag
75 | false, // direction flag
76 | false, // overflow flag
77 |
78 | false, // 12 reserved
79 | true, // 13 reserved
80 | true, // 14 reserved
81 | true, // 15 reserved
82 | ]);
83 |
84 | $this->flippedNames = array_flip(self::NAMES);
85 | }
86 |
87 | public function __toString(): string
88 | {
89 | $a = $this->data->toArray();
90 | $a = array_reverse($a);
91 | $n = array_map(function ($f) {
92 | return $f ? '1' : 0;
93 | }, $a);
94 | $s = join('', $n);
95 | $s = sprintf('FLAGS[%s,%04x]', $s, $this->toInt());
96 | return $s;
97 | }
98 |
99 | public function getSize(): int
100 | {
101 | return self::SIZE;
102 | }
103 |
104 | public function set(int $flagId, bool $val): void
105 | {
106 | /**
107 | * @link https://en.wikipedia.org/wiki/FLAGS_register
108 | */
109 | if (1 === $flagId || $flagId >= 13) {
110 | $val = true;
111 | }
112 | if (12 === $flagId) {
113 | exit(1);
114 | // throw new \RuntimeException('Since we use FLAG 12 as Always-Zero FLAG we cannot override it.');
115 | }
116 | $this->data[$flagId] = $val;
117 | }
118 |
119 | public function setByName(string $name, bool $val): void
120 | {
121 | $this->set(self::NAMES[$name], $val);
122 | }
123 |
124 | public function get(int $flagId): bool
125 | {
126 | $f = boolval($this->data[$flagId]);
127 | return $f;
128 | }
129 |
130 | public function getByName(string $name): bool
131 | {
132 | return $this->get(self::NAMES[$name]);
133 | }
134 |
135 | public function getName(int $flagId): string
136 | {
137 | return $this->flippedNames[$flagId];
138 | }
139 |
140 | public function setIntData(int $data): void
141 | {
142 | foreach ($this->data as $i => $f) {
143 | if (12 !== $i) {
144 | $this->set($i, $data & 1);
145 | }
146 | $data >>= 1;
147 | }
148 | }
149 |
150 | public function setData(iterable $data): void
151 | {
152 | $n = ($data[1] << 8) | $data[0];
153 | $this->setIntData($n);
154 | }
155 |
156 | public function getData(): \SplFixedArray
157 | {
158 | $data = new \SplFixedArray(self::SIZE);
159 |
160 | for ($j = 0; $j < 2; ++$j) {
161 | $data[$j] = 0;
162 | for ($i = 0; $i < 8; ++$i) {
163 | $n = $this->data[$j * 8 + $i] << $i;
164 | $data[$j] |= $n;
165 | }
166 | }
167 |
168 | return $data;
169 | }
170 |
171 | public function getStandardizedData(): \SplFixedArray
172 | {
173 | $data = $this->getData();
174 | $data[1] |= 0xF0;
175 | $data[0] |= 0x2;
176 | return $data;
177 | }
178 |
179 | public function toInt(): int
180 | {
181 | $i = 0;
182 | $bits = 0;
183 | foreach ($this->data as $f) {
184 | $i |= $f << $bits;
185 | ++$bits;
186 | }
187 | return $i;
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/src/Components/Address.php:
--------------------------------------------------------------------------------
1 | setSize($size);
76 | $this->setData($data);
77 | }
78 |
79 | public function __toString(): string
80 | {
81 | $format = sprintf('ADDR[%%0%dx]', $this->getSize() << 1);
82 | $s = sprintf($format, $this->toInt());
83 | return $s;
84 | }
85 |
86 | public function setSize(int $size = 2): void
87 | {
88 | if ($size > PHP_INT_SIZE) {
89 | throw new ValueExceededException(sprintf('Size cannot exceed PHP_INT_SIZE. (%d)', PHP_INT_SIZE));
90 | }
91 |
92 | $this->size = $size;
93 | $this->halfSize = $this->size >> 1;
94 | if ($this->halfSize < 1) {
95 | $this->halfSize = 1;
96 | }
97 |
98 | $this->maxValue = (1 << ($this->size << 3)) - 1;
99 |
100 | $this->halfBits = $this->halfSize << 3; // * 8
101 | $this->lowMask = (1 << $this->halfBits) - 1;
102 | $this->effectiveHighMask = $this->lowMask << $this->halfBits;
103 | }
104 |
105 | /**
106 | * @return int
107 | */
108 | public function getSize(): int
109 | {
110 | return $this->size;
111 | }
112 |
113 | public function getHalfSize(): int
114 | {
115 | return $this->halfSize;
116 | }
117 |
118 | /**
119 | * @return int
120 | */
121 | public function getHalfBits(): int
122 | {
123 | return $this->halfBits;
124 | }
125 |
126 | /**
127 | * @return int
128 | */
129 | public function toInt(): int
130 | {
131 | return $this->dataInt;
132 | }
133 |
134 | public function setLowInt(int $low): int
135 | {
136 | $l = $low & $this->lowMask;
137 | $h = $this->dataEffectiveHighInt;
138 | $n = $h | $l;
139 | $this->setData($n);
140 |
141 | return $n;
142 | }
143 |
144 | public function getLowInt(): int
145 | {
146 | return $this->dataLowInt;
147 | }
148 |
149 | public function setHighInt(int $high): int
150 | {
151 | $l = $this->dataLowInt;
152 | $h = ($high << $this->halfBits) & $this->effectiveHighMask;
153 | $n = $h | $l;
154 | $this->setData($n);
155 |
156 | return $n;
157 | }
158 |
159 | public function getHighInt(): int
160 | {
161 | return $this->dataHighInt;
162 | }
163 |
164 | public function getEffectiveHighInt(): int
165 | {
166 | return $this->dataEffectiveHighInt;
167 | }
168 |
169 | /**
170 | * Overwrite all fields.
171 | *
172 | * @param iterable|int $data
173 | * @param bool $reset Keeps the original data of the fields that has not been touched when false.
174 | */
175 | public function setData($data, bool $reset = true): void
176 | {
177 | $this->dataInt = 0;
178 | if ($reset) {
179 | $this->dataBytes = new \SplFixedArray($this->size);
180 | }
181 |
182 | if (is_iterable($data)) {
183 | $length = count($data);
184 | $bits = 0;
185 | $offset = 0;
186 | while ($offset < $this->size && $offset < $length) {
187 | $c = $data[$offset];
188 | $this->dataInt += $c << $bits;
189 | $this->dataBytes[$offset] = $c;
190 |
191 | ++$offset;
192 | $bits += 8;
193 | }
194 | } elseif (is_numeric($data)) {
195 | //if ($data < 0) {
196 | // throw new NegativeValueException();
197 | //}
198 |
199 | $this->dataInt = $data & $this->maxValue;
200 | //$debug=sprintf("data int: %08x\n", $this->dataInt);
201 |
202 | $offset = 0;
203 | while (0 !== $data && $offset < $this->size) {
204 | $this->dataBytes[$offset] = $data & 0xFF;
205 |
206 | $data >>= 8;
207 | ++$offset;
208 | }
209 | }
210 |
211 | $this->dataLowInt = $this->dataInt & $this->lowMask;
212 | $this->dataHighInt = $this->dataInt >> $this->halfBits;
213 | $this->dataEffectiveHighInt = $this->dataInt & $this->effectiveHighMask;
214 | }
215 |
216 | /**
217 | * @return \SplFixedArray
218 | */
219 | public function getData(): \SplFixedArray
220 | {
221 | return $this->dataBytes;
222 | }
223 |
224 | public function add(int $i): int
225 | {
226 | if (0 !== $i) {
227 | $endVal = $this->dataInt + $i;
228 | $this->setData($endVal);
229 | }
230 |
231 | return $this->dataInt;
232 | }
233 |
234 | public function sub(int $i): int
235 | {
236 | if (0 !== $i) {
237 | $endVal = $this->dataInt - $i;
238 | $this->setData($endVal);
239 | }
240 |
241 | return $this->dataInt;
242 | }
243 | }
244 |
--------------------------------------------------------------------------------
/php/php.ini:
--------------------------------------------------------------------------------
1 | [PHP]
2 |
3 | ;;;;;;;;;;;;;;;;;;;
4 | ; About php.ini ;
5 | ;;;;;;;;;;;;;;;;;;;
6 | ; PHP's initialization file, generally called php.ini, is responsible for
7 | ; configuring many of the aspects of PHP's behavior.
8 |
9 | ; PHP attempts to find and load this configuration from a number of locations.
10 | ; The following is a summary of its search order:
11 | ; 1. SAPI module specific location.
12 | ; 2. The PHPRC environment variable. (As of PHP 5.2.0)
13 | ; 3. A number of predefined registry keys on Windows (As of PHP 5.2.0)
14 | ; 4. Current working directory (except CLI)
15 | ; 5. The web server's directory (for SAPI modules), or directory of PHP
16 | ; (otherwise in Windows)
17 | ; 6. The directory from the --with-config-file-path compile time option, or the
18 | ; Windows directory (usually C:\windows)
19 | ; See the PHP docs for more specific information.
20 | ; http://php.net/configuration.file
21 |
22 | ; The syntax of the file is extremely simple. Whitespace and lines
23 | ; beginning with a semicolon are silently ignored (as you probably guessed).
24 | ; Section headers (e.g. [Foo]) are also silently ignored, even though
25 | ; they might mean something in the future.
26 |
27 | ; Directives following the section heading [PATH=/www/mysite] only
28 | ; apply to PHP files in the /www/mysite directory. Directives
29 | ; following the section heading [HOST=www.example.com] only apply to
30 | ; PHP files served from www.example.com. Directives set in these
31 | ; special sections cannot be overridden by user-defined INI files or
32 | ; at runtime. Currently, [PATH=] and [HOST=] sections only work under
33 | ; CGI/FastCGI.
34 | ; http://php.net/ini.sections
35 |
36 | ; Directives are specified using the following syntax:
37 | ; directive = value
38 | ; Directive names are *case sensitive* - foo=bar is different from FOO=bar.
39 | ; Directives are variables used to configure PHP or PHP extensions.
40 | ; There is no name validation. If PHP can't find an expected
41 | ; directive because it is not set or is mistyped, a default value will be used.
42 |
43 | ; The value can be a string, a number, a PHP constant (e.g. E_ALL or M_PI), one
44 | ; of the INI constants (On, Off, True, False, Yes, No and None) or an expression
45 | ; (e.g. E_ALL & ~E_NOTICE), a quoted string ("bar"), or a reference to a
46 | ; previously set variable or directive (e.g. ${foo})
47 |
48 | ; Expressions in the INI file are limited to bitwise operators and parentheses:
49 | ; | bitwise OR
50 | ; ^ bitwise XOR
51 | ; & bitwise AND
52 | ; ~ bitwise NOT
53 | ; ! boolean NOT
54 |
55 | ; Boolean flags can be turned on using the values 1, On, True or Yes.
56 | ; They can be turned off using the values 0, Off, False or No.
57 |
58 | ; An empty string can be denoted by simply not writing anything after the equal
59 | ; sign, or by using the None keyword:
60 |
61 | ; foo = ; sets foo to an empty string
62 | ; foo = None ; sets foo to an empty string
63 | ; foo = "None" ; sets foo to the string 'None'
64 |
65 | ; If you use constants in your value, and these constants belong to a
66 | ; dynamically loaded extension (either a PHP extension or a Zend extension),
67 | ; you may only use these constants *after* the line that loads the extension.
68 |
69 | ;;;;;;;;;;;;;;;;;;;
70 | ; About this file ;
71 | ;;;;;;;;;;;;;;;;;;;
72 | ; PHP comes packaged with two INI files. One that is recommended to be used
73 | ; in production environments and one that is recommended to be used in
74 | ; development environments.
75 |
76 | ; php.ini-production contains settings which hold security, performance and
77 | ; best practices at its core. But please be aware, these settings may break
78 | ; compatibility with older or less security conscience applications. We
79 | ; recommending using the production ini in production and testing environments.
80 |
81 | ; php.ini-development is very similar to its production variant, except it is
82 | ; much more verbose when it comes to errors. We recommend using the
83 | ; development version only in development environments, as errors shown to
84 | ; application users can inadvertently leak otherwise secure information.
85 |
86 | ; This is the php.ini-production INI file.
87 |
88 | ;;;;;;;;;;;;;;;;;;;
89 | ; Quick Reference ;
90 | ;;;;;;;;;;;;;;;;;;;
91 | ; The following are all the settings which are different in either the production
92 | ; or development versions of the INIs with respect to PHP's default behavior.
93 | ; Please see the actual settings later in the document for more details as to why
94 | ; we recommend these changes in PHP's behavior.
95 |
96 | ; display_errors
97 | ; Default Value: On
98 | ; Development Value: On
99 | ; Production Value: Off
100 |
101 | ; display_startup_errors
102 | ; Default Value: Off
103 | ; Development Value: On
104 | ; Production Value: Off
105 |
106 | ; error_reporting
107 | ; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
108 | ; Development Value: E_ALL
109 | ; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
110 |
111 | ; html_errors
112 | ; Default Value: On
113 | ; Development Value: On
114 | ; Production value: On
115 |
116 | ; log_errors
117 | ; Default Value: Off
118 | ; Development Value: On
119 | ; Production Value: On
120 |
121 | ; max_input_time
122 | ; Default Value: -1 (Unlimited)
123 | ; Development Value: 60 (60 seconds)
124 | ; Production Value: 60 (60 seconds)
125 |
126 | ; output_buffering
127 | ; Default Value: Off
128 | ; Development Value: 4096
129 | ; Production Value: 4096
130 |
131 | ; register_argc_argv
132 | ; Default Value: On
133 | ; Development Value: Off
134 | ; Production Value: Off
135 |
136 | ; request_order
137 | ; Default Value: None
138 | ; Development Value: "GP"
139 | ; Production Value: "GP"
140 |
141 | ; session.gc_divisor
142 | ; Default Value: 100
143 | ; Development Value: 1000
144 | ; Production Value: 1000
145 |
146 | ; session.sid_bits_per_character
147 | ; Default Value: 4
148 | ; Development Value: 5
149 | ; Production Value: 5
150 |
151 | ; short_open_tag
152 | ; Default Value: On
153 | ; Development Value: Off
154 | ; Production Value: Off
155 |
156 | ; track_errors
157 | ; Default Value: Off
158 | ; Development Value: On
159 | ; Production Value: Off
160 |
161 | ; variables_order
162 | ; Default Value: "EGPCS"
163 | ; Development Value: "GPCS"
164 | ; Production Value: "GPCS"
165 |
166 | ;;;;;;;;;;;;;;;;;;;;
167 | ; php.ini Options ;
168 | ;;;;;;;;;;;;;;;;;;;;
169 | ; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini"
170 | ;user_ini.filename = ".user.ini"
171 |
172 | ; To disable this feature set this option to an empty value
173 | ;user_ini.filename =
174 |
175 | ; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes)
176 | ;user_ini.cache_ttl = 300
177 |
178 | ;;;;;;;;;;;;;;;;;;;;
179 | ; Language Options ;
180 | ;;;;;;;;;;;;;;;;;;;;
181 |
182 | ; Enable the PHP scripting language engine under Apache.
183 | ; http://php.net/engine
184 | engine = On
185 |
186 | ; This directive determines whether or not PHP will recognize code between
187 | ; and ?> tags as PHP source which should be processed as such. It is
188 | ; generally recommended that should be used and that this feature
189 | ; should be disabled, as enabling it may result in issues when generating XML
190 | ; documents, however this remains supported for backward compatibility reasons.
191 | ; Note that this directive does not control the = shorthand tag, which can be
192 | ; used regardless of this directive.
193 | ; Default Value: On
194 | ; Development Value: Off
195 | ; Production Value: Off
196 | ; http://php.net/short-open-tag
197 | short_open_tag = Off
198 |
199 | ; The number of significant digits displayed in floating point numbers.
200 | ; http://php.net/precision
201 | precision = 14
202 |
203 | ; Output buffering is a mechanism for controlling how much output data
204 | ; (excluding headers and cookies) PHP should keep internally before pushing that
205 | ; data to the client. If your application's output exceeds this setting, PHP
206 | ; will send that data in chunks of roughly the size you specify.
207 | ; Turning on this setting and managing its maximum buffer size can yield some
208 | ; interesting side-effects depending on your application and web server.
209 | ; You may be able to send headers and cookies after you've already sent output
210 | ; through print or echo. You also may see performance benefits if your server is
211 | ; emitting less packets due to buffered output versus PHP streaming the output
212 | ; as it gets it. On production servers, 4096 bytes is a good setting for performance
213 | ; reasons.
214 | ; Note: Output buffering can also be controlled via Output Buffering Control
215 | ; functions.
216 | ; Possible Values:
217 | ; On = Enabled and buffer is unlimited. (Use with caution)
218 | ; Off = Disabled
219 | ; Integer = Enables the buffer and sets its maximum size in bytes.
220 | ; Note: This directive is hardcoded to Off for the CLI SAPI
221 | ; Default Value: Off
222 | ; Development Value: 4096
223 | ; Production Value: 4096
224 | ; http://php.net/output-buffering
225 | output_buffering = 4096
226 |
227 | ; You can redirect all of the output of your scripts to a function. For
228 | ; example, if you set output_handler to "mb_output_handler", character
229 | ; encoding will be transparently converted to the specified encoding.
230 | ; Setting any output handler automatically turns on output buffering.
231 | ; Note: People who wrote portable scripts should not depend on this ini
232 | ; directive. Instead, explicitly set the output handler using ob_start().
233 | ; Using this ini directive may cause problems unless you know what script
234 | ; is doing.
235 | ; Note: You cannot use both "mb_output_handler" with "ob_iconv_handler"
236 | ; and you cannot use both "ob_gzhandler" and "zlib.output_compression".
237 | ; Note: output_handler must be empty if this is set 'On' !!!!
238 | ; Instead you must use zlib.output_handler.
239 | ; http://php.net/output-handler
240 | ;output_handler =
241 |
242 | ; URL rewriter function rewrites URL on the fly by using
243 | ; output buffer. You can set target tags by this configuration.
244 | ; "form" tag is special tag. It will add hidden input tag to pass values.
245 | ; Refer to session.trans_sid_tags for usage.
246 | ; Default Value: "form="
247 | ; Development Value: "form="
248 | ; Production Value: "form="
249 | ;url_rewriter.tags
250 |
251 | ; URL rewriter will not rewrite absolute URL nor form by default. To enable
252 | ; absolute URL rewrite, allowed hosts must be defined at RUNTIME.
253 | ; Refer to session.trans_sid_hosts for more details.
254 | ; Default Value: ""
255 | ; Development Value: ""
256 | ; Production Value: ""
257 | ;url_rewriter.hosts
258 |
259 | ; Transparent output compression using the zlib library
260 | ; Valid values for this option are 'off', 'on', or a specific buffer size
261 | ; to be used for compression (default is 4KB)
262 | ; Note: Resulting chunk size may vary due to nature of compression. PHP
263 | ; outputs chunks that are few hundreds bytes each as a result of
264 | ; compression. If you prefer a larger chunk size for better
265 | ; performance, enable output_buffering in addition.
266 | ; Note: You need to use zlib.output_handler instead of the standard
267 | ; output_handler, or otherwise the output will be corrupted.
268 | ; http://php.net/zlib.output-compression
269 | zlib.output_compression = Off
270 |
271 | ; http://php.net/zlib.output-compression-level
272 | ;zlib.output_compression_level = -1
273 |
274 | ; You cannot specify additional output handlers if zlib.output_compression
275 | ; is activated here. This setting does the same as output_handler but in
276 | ; a different order.
277 | ; http://php.net/zlib.output-handler
278 | ;zlib.output_handler =
279 |
280 | ; Implicit flush tells PHP to tell the output layer to flush itself
281 | ; automatically after every output block. This is equivalent to calling the
282 | ; PHP function flush() after each and every call to print() or echo() and each
283 | ; and every HTML block. Turning this option on has serious performance
284 | ; implications and is generally recommended for debugging purposes only.
285 | ; http://php.net/implicit-flush
286 | ; Note: This directive is hardcoded to On for the CLI SAPI
287 | implicit_flush = Off
288 |
289 | ; The unserialize callback function will be called (with the undefined class'
290 | ; name as parameter), if the unserializer finds an undefined class
291 | ; which should be instantiated. A warning appears if the specified function is
292 | ; not defined, or if the function doesn't include/implement the missing class.
293 | ; So only set this entry, if you really want to implement such a
294 | ; callback-function.
295 | unserialize_callback_func =
296 |
297 | ; When floats & doubles are serialized, store serialize_precision significant
298 | ; digits after the floating point. The default value ensures that when floats
299 | ; are decoded with unserialize, the data will remain the same.
300 | ; The value is also used for json_encode when encoding double values.
301 | ; If -1 is used, then dtoa mode 0 is used which automatically select the best
302 | ; precision.
303 | serialize_precision = -1
304 |
305 | ; open_basedir, if set, limits all file operations to the defined directory
306 | ; and below. This directive makes most sense if used in a per-directory
307 | ; or per-virtualhost web server configuration file.
308 | ; http://php.net/open-basedir
309 | ;open_basedir =
310 |
311 | ; This directive allows you to disable certain functions for security reasons.
312 | ; It receives a comma-delimited list of function names.
313 | ; http://php.net/disable-functions
314 | disable_functions =
315 |
316 | ; This directive allows you to disable certain classes for security reasons.
317 | ; It receives a comma-delimited list of class names.
318 | ; http://php.net/disable-classes
319 | disable_classes =
320 |
321 | ; Colors for Syntax Highlighting mode. Anything that's acceptable in
322 | ; would work.
323 | ; http://php.net/syntax-highlighting
324 | ;highlight.string = #DD0000
325 | ;highlight.comment = #FF9900
326 | ;highlight.keyword = #007700
327 | ;highlight.default = #0000BB
328 | ;highlight.html = #000000
329 |
330 | ; If enabled, the request will be allowed to complete even if the user aborts
331 | ; the request. Consider enabling it if executing long requests, which may end up
332 | ; being interrupted by the user or a browser timing out. PHP's default behavior
333 | ; is to disable this feature.
334 | ; http://php.net/ignore-user-abort
335 | ;ignore_user_abort = On
336 |
337 | ; Determines the size of the realpath cache to be used by PHP. This value should
338 | ; be increased on systems where PHP opens many files to reflect the quantity of
339 | ; the file operations performed.
340 | ; http://php.net/realpath-cache-size
341 | ;realpath_cache_size = 4096k
342 |
343 | ; Duration of time, in seconds for which to cache realpath information for a given
344 | ; file or directory. For systems with rarely changing files, consider increasing this
345 | ; value.
346 | ; http://php.net/realpath-cache-ttl
347 | ;realpath_cache_ttl = 120
348 |
349 | ; Enables or disables the circular reference collector.
350 | ; http://php.net/zend.enable-gc
351 | zend.enable_gc = On
352 |
353 | ; If enabled, scripts may be written in encodings that are incompatible with
354 | ; the scanner. CP936, Big5, CP949 and Shift_JIS are the examples of such
355 | ; encodings. To use this feature, mbstring extension must be enabled.
356 | ; Default: Off
357 | ;zend.multibyte = Off
358 |
359 | ; Allows to set the default encoding for the scripts. This value will be used
360 | ; unless "declare(encoding=...)" directive appears at the top of the script.
361 | ; Only affects if zend.multibyte is set.
362 | ; Default: ""
363 | ;zend.script_encoding =
364 |
365 | ;;;;;;;;;;;;;;;;;
366 | ; Miscellaneous ;
367 | ;;;;;;;;;;;;;;;;;
368 |
369 | ; Decides whether PHP may expose the fact that it is installed on the server
370 | ; (e.g. by adding its signature to the Web server header). It is no security
371 | ; threat in any way, but it makes it possible to determine whether you use PHP
372 | ; on your server or not.
373 | ; http://php.net/expose-php
374 | expose_php = On
375 |
376 | ;;;;;;;;;;;;;;;;;;;
377 | ; Resource Limits ;
378 | ;;;;;;;;;;;;;;;;;;;
379 |
380 | ; Maximum execution time of each script, in seconds
381 | ; http://php.net/max-execution-time
382 | ; Note: This directive is hardcoded to 0 for the CLI SAPI
383 | max_execution_time = 30
384 |
385 | ; Maximum amount of time each script may spend parsing request data. It's a good
386 | ; idea to limit this time on productions servers in order to eliminate unexpectedly
387 | ; long running scripts.
388 | ; Note: This directive is hardcoded to -1 for the CLI SAPI
389 | ; Default Value: -1 (Unlimited)
390 | ; Development Value: 60 (60 seconds)
391 | ; Production Value: 60 (60 seconds)
392 | ; http://php.net/max-input-time
393 | max_input_time = 60
394 |
395 | ; Maximum input variable nesting level
396 | ; http://php.net/max-input-nesting-level
397 | ;max_input_nesting_level = 64
398 |
399 | ; How many GET/POST/COOKIE input variables may be accepted
400 | ;max_input_vars = 1000
401 |
402 | ; Maximum amount of memory a script may consume (128MB)
403 | ; http://php.net/memory-limit
404 | memory_limit = -1
405 |
406 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
407 | ; Error handling and logging ;
408 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
409 |
410 | ; This directive informs PHP of which errors, warnings and notices you would like
411 | ; it to take action for. The recommended way of setting values for this
412 | ; directive is through the use of the error level constants and bitwise
413 | ; operators. The error level constants are below here for convenience as well as
414 | ; some common settings and their meanings.
415 | ; By default, PHP is set to take action on all errors, notices and warnings EXCEPT
416 | ; those related to E_NOTICE and E_STRICT, which together cover best practices and
417 | ; recommended coding standards in PHP. For performance reasons, this is the
418 | ; recommend error reporting setting. Your production server shouldn't be wasting
419 | ; resources complaining about best practices and coding standards. That's what
420 | ; development servers and development settings are for.
421 | ; Note: The php.ini-development file has this setting as E_ALL. This
422 | ; means it pretty much reports everything which is exactly what you want during
423 | ; development and early testing.
424 | ;
425 | ; Error Level Constants:
426 | ; E_ALL - All errors and warnings (includes E_STRICT as of PHP 5.4.0)
427 | ; E_ERROR - fatal run-time errors
428 | ; E_RECOVERABLE_ERROR - almost fatal run-time errors
429 | ; E_WARNING - run-time warnings (non-fatal errors)
430 | ; E_PARSE - compile-time parse errors
431 | ; E_NOTICE - run-time notices (these are warnings which often result
432 | ; from a bug in your code, but it's possible that it was
433 | ; intentional (e.g., using an uninitialized variable and
434 | ; relying on the fact it is automatically initialized to an
435 | ; empty string)
436 | ; E_STRICT - run-time notices, enable to have PHP suggest changes
437 | ; to your code which will ensure the best interoperability
438 | ; and forward compatibility of your code
439 | ; E_CORE_ERROR - fatal errors that occur during PHP's initial startup
440 | ; E_CORE_WARNING - warnings (non-fatal errors) that occur during PHP's
441 | ; initial startup
442 | ; E_COMPILE_ERROR - fatal compile-time errors
443 | ; E_COMPILE_WARNING - compile-time warnings (non-fatal errors)
444 | ; E_USER_ERROR - user-generated error message
445 | ; E_USER_WARNING - user-generated warning message
446 | ; E_USER_NOTICE - user-generated notice message
447 | ; E_DEPRECATED - warn about code that will not work in future versions
448 | ; of PHP
449 | ; E_USER_DEPRECATED - user-generated deprecation warnings
450 | ;
451 | ; Common Values:
452 | ; E_ALL (Show all errors, warnings and notices including coding standards.)
453 | ; E_ALL & ~E_NOTICE (Show all errors, except for notices)
454 | ; E_ALL & ~E_NOTICE & ~E_STRICT (Show all errors, except for notices and coding standards warnings.)
455 | ; E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR (Show only errors)
456 | ; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
457 | ; Development Value: E_ALL
458 | ; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
459 | ; http://php.net/error-reporting
460 | error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
461 |
462 | ; This directive controls whether or not and where PHP will output errors,
463 | ; notices and warnings too. Error output is very useful during development, but
464 | ; it could be very dangerous in production environments. Depending on the code
465 | ; which is triggering the error, sensitive information could potentially leak
466 | ; out of your application such as database usernames and passwords or worse.
467 | ; For production environments, we recommend logging errors rather than
468 | ; sending them to STDOUT.
469 | ; Possible Values:
470 | ; Off = Do not display any errors
471 | ; stderr = Display errors to STDERR (affects only CGI/CLI binaries!)
472 | ; On or stdout = Display errors to STDOUT
473 | ; Default Value: On
474 | ; Development Value: On
475 | ; Production Value: Off
476 | ; http://php.net/display-errors
477 | display_errors = Off
478 |
479 | ; The display of errors which occur during PHP's startup sequence are handled
480 | ; separately from display_errors. PHP's default behavior is to suppress those
481 | ; errors from clients. Turning the display of startup errors on can be useful in
482 | ; debugging configuration problems. We strongly recommend you
483 | ; set this to 'off' for production servers.
484 | ; Default Value: Off
485 | ; Development Value: On
486 | ; Production Value: Off
487 | ; http://php.net/display-startup-errors
488 | display_startup_errors = Off
489 |
490 | ; Besides displaying errors, PHP can also log errors to locations such as a
491 | ; server-specific log, STDERR, or a location specified by the error_log
492 | ; directive found below. While errors should not be displayed on productions
493 | ; servers they should still be monitored and logging is a great way to do that.
494 | ; Default Value: Off
495 | ; Development Value: On
496 | ; Production Value: On
497 | ; http://php.net/log-errors
498 | log_errors = On
499 |
500 | ; Set maximum length of log_errors. In error_log information about the source is
501 | ; added. The default is 1024 and 0 allows to not apply any maximum length at all.
502 | ; http://php.net/log-errors-max-len
503 | log_errors_max_len = 1024
504 |
505 | ; Do not log repeated messages. Repeated errors must occur in same file on same
506 | ; line unless ignore_repeated_source is set true.
507 | ; http://php.net/ignore-repeated-errors
508 | ignore_repeated_errors = Off
509 |
510 | ; Ignore source of message when ignoring repeated messages. When this setting
511 | ; is On you will not log errors with repeated messages from different files or
512 | ; source lines.
513 | ; http://php.net/ignore-repeated-source
514 | ignore_repeated_source = Off
515 |
516 | ; If this parameter is set to Off, then memory leaks will not be shown (on
517 | ; stdout or in the log). This has only effect in a debug compile, and if
518 | ; error reporting includes E_WARNING in the allowed list
519 | ; http://php.net/report-memleaks
520 | report_memleaks = On
521 |
522 | ; This setting is on by default.
523 | ;report_zend_debug = 0
524 |
525 | ; Store the last error/warning message in $php_errormsg (boolean). Setting this value
526 | ; to On can assist in debugging and is appropriate for development servers. It should
527 | ; however be disabled on production servers.
528 | ; This directive is DEPRECATED.
529 | ; Default Value: Off
530 | ; Development Value: Off
531 | ; Production Value: Off
532 | ; http://php.net/track-errors
533 | ;track_errors = Off
534 |
535 | ; Turn off normal error reporting and emit XML-RPC error XML
536 | ; http://php.net/xmlrpc-errors
537 | ;xmlrpc_errors = 0
538 |
539 | ; An XML-RPC faultCode
540 | ;xmlrpc_error_number = 0
541 |
542 | ; When PHP displays or logs an error, it has the capability of formatting the
543 | ; error message as HTML for easier reading. This directive controls whether
544 | ; the error message is formatted as HTML or not.
545 | ; Note: This directive is hardcoded to Off for the CLI SAPI
546 | ; Default Value: On
547 | ; Development Value: On
548 | ; Production value: On
549 | ; http://php.net/html-errors
550 | html_errors = On
551 |
552 | ; If html_errors is set to On *and* docref_root is not empty, then PHP
553 | ; produces clickable error messages that direct to a page describing the error
554 | ; or function causing the error in detail.
555 | ; You can download a copy of the PHP manual from http://php.net/docs
556 | ; and change docref_root to the base URL of your local copy including the
557 | ; leading '/'. You must also specify the file extension being used including
558 | ; the dot. PHP's default behavior is to leave these settings empty, in which
559 | ; case no links to documentation are generated.
560 | ; Note: Never use this feature for production boxes.
561 | ; http://php.net/docref-root
562 | ; Examples
563 | ;docref_root = "/phpmanual/"
564 |
565 | ; http://php.net/docref-ext
566 | ;docref_ext = .html
567 |
568 | ; String to output before an error message. PHP's default behavior is to leave
569 | ; this setting blank.
570 | ; http://php.net/error-prepend-string
571 | ; Example:
572 | ;error_prepend_string = ""
573 |
574 | ; String to output after an error message. PHP's default behavior is to leave
575 | ; this setting blank.
576 | ; http://php.net/error-append-string
577 | ; Example:
578 | ;error_append_string = ""
579 |
580 | ; Log errors to specified file. PHP's default behavior is to leave this value
581 | ; empty.
582 | ; http://php.net/error-log
583 | ; Example:
584 | ;error_log = php_errors.log
585 | ; Log errors to syslog (Event Log on Windows).
586 | ;error_log = syslog
587 |
588 | ; The syslog ident is a string which is prepended to every message logged
589 | ; to syslog. Only used when error_log is set to syslog.
590 | ;syslog.ident = php
591 |
592 | ; The syslog facility is used to specify what type of program is logging
593 | ; the message. Only used when error_log is set to syslog.
594 | ;syslog.facility = user
595 |
596 | ;windows.show_crt_warning
597 | ; Default value: 0
598 | ; Development value: 0
599 | ; Production value: 0
600 |
601 | ;;;;;;;;;;;;;;;;;
602 | ; Data Handling ;
603 | ;;;;;;;;;;;;;;;;;
604 |
605 | ; The separator used in PHP generated URLs to separate arguments.
606 | ; PHP's default setting is "&".
607 | ; http://php.net/arg-separator.output
608 | ; Example:
609 | ;arg_separator.output = "&"
610 |
611 | ; List of separator(s) used by PHP to parse input URLs into variables.
612 | ; PHP's default setting is "&".
613 | ; NOTE: Every character in this directive is considered as separator!
614 | ; http://php.net/arg-separator.input
615 | ; Example:
616 | ;arg_separator.input = ";&"
617 |
618 | ; This directive determines which super global arrays are registered when PHP
619 | ; starts up. G,P,C,E & S are abbreviations for the following respective super
620 | ; globals: GET, POST, COOKIE, ENV and SERVER. There is a performance penalty
621 | ; paid for the registration of these arrays and because ENV is not as commonly
622 | ; used as the others, ENV is not recommended on productions servers. You
623 | ; can still get access to the environment variables through getenv() should you
624 | ; need to.
625 | ; Default Value: "EGPCS"
626 | ; Development Value: "GPCS"
627 | ; Production Value: "GPCS";
628 | ; http://php.net/variables-order
629 | variables_order = "GPCS"
630 |
631 | ; This directive determines which super global data (G,P & C) should be
632 | ; registered into the super global array REQUEST. If so, it also determines
633 | ; the order in which that data is registered. The values for this directive
634 | ; are specified in the same manner as the variables_order directive,
635 | ; EXCEPT one. Leaving this value empty will cause PHP to use the value set
636 | ; in the variables_order directive. It does not mean it will leave the super
637 | ; globals array REQUEST empty.
638 | ; Default Value: None
639 | ; Development Value: "GP"
640 | ; Production Value: "GP"
641 | ; http://php.net/request-order
642 | request_order = "GP"
643 |
644 | ; This directive determines whether PHP registers $argv & $argc each time it
645 | ; runs. $argv contains an array of all the arguments passed to PHP when a script
646 | ; is invoked. $argc contains an integer representing the number of arguments
647 | ; that were passed when the script was invoked. These arrays are extremely
648 | ; useful when running scripts from the command line. When this directive is
649 | ; enabled, registering these variables consumes CPU cycles and memory each time
650 | ; a script is executed. For performance reasons, this feature should be disabled
651 | ; on production servers.
652 | ; Note: This directive is hardcoded to On for the CLI SAPI
653 | ; Default Value: On
654 | ; Development Value: Off
655 | ; Production Value: Off
656 | ; http://php.net/register-argc-argv
657 | register_argc_argv = Off
658 |
659 | ; When enabled, the ENV, REQUEST and SERVER variables are created when they're
660 | ; first used (Just In Time) instead of when the script starts. If these
661 | ; variables are not used within a script, having this directive on will result
662 | ; in a performance gain. The PHP directive register_argc_argv must be disabled
663 | ; for this directive to have any affect.
664 | ; http://php.net/auto-globals-jit
665 | auto_globals_jit = On
666 |
667 | ; Whether PHP will read the POST data.
668 | ; This option is enabled by default.
669 | ; Most likely, you won't want to disable this option globally. It causes $_POST
670 | ; and $_FILES to always be empty; the only way you will be able to read the
671 | ; POST data will be through the php://input stream wrapper. This can be useful
672 | ; to proxy requests or to process the POST data in a memory efficient fashion.
673 | ; http://php.net/enable-post-data-reading
674 | ;enable_post_data_reading = Off
675 |
676 | ; Maximum size of POST data that PHP will accept.
677 | ; Its value may be 0 to disable the limit. It is ignored if POST data reading
678 | ; is disabled through enable_post_data_reading.
679 | ; http://php.net/post-max-size
680 | post_max_size = 8M
681 |
682 | ; Automatically add files before PHP document.
683 | ; http://php.net/auto-prepend-file
684 | auto_prepend_file =
685 |
686 | ; Automatically add files after PHP document.
687 | ; http://php.net/auto-append-file
688 | auto_append_file =
689 |
690 | ; By default, PHP will output a media type using the Content-Type header. To
691 | ; disable this, simply set it to be empty.
692 | ;
693 | ; PHP's built-in default media type is set to text/html.
694 | ; http://php.net/default-mimetype
695 | default_mimetype = "text/html"
696 |
697 | ; PHP's default character set is set to UTF-8.
698 | ; http://php.net/default-charset
699 | default_charset = "UTF-8"
700 |
701 | ; PHP internal character encoding is set to empty.
702 | ; If empty, default_charset is used.
703 | ; http://php.net/internal-encoding
704 | ;internal_encoding =
705 |
706 | ; PHP input character encoding is set to empty.
707 | ; If empty, default_charset is used.
708 | ; http://php.net/input-encoding
709 | ;input_encoding =
710 |
711 | ; PHP output character encoding is set to empty.
712 | ; If empty, default_charset is used.
713 | ; See also output_buffer.
714 | ; http://php.net/output-encoding
715 | ;output_encoding =
716 |
717 | ;;;;;;;;;;;;;;;;;;;;;;;;;
718 | ; Paths and Directories ;
719 | ;;;;;;;;;;;;;;;;;;;;;;;;;
720 |
721 | ; UNIX: "/path1:/path2"
722 | ;include_path = ".:/usr/share/php"
723 | ;
724 | ; Windows: "\path1;\path2"
725 | ;include_path = ".;c:\php\includes"
726 | ;
727 | ; PHP's default setting for include_path is ".;/path/to/php/pear"
728 | ; http://php.net/include-path
729 |
730 | ; The root of the PHP pages, used only if nonempty.
731 | ; if PHP was not compiled with FORCE_REDIRECT, you SHOULD set doc_root
732 | ; if you are running php as a CGI under any web server (other than IIS)
733 | ; see documentation for security issues. The alternate is to use the
734 | ; cgi.force_redirect configuration below
735 | ; http://php.net/doc-root
736 | doc_root =
737 |
738 | ; The directory under which PHP opens the script using /~username used only
739 | ; if nonempty.
740 | ; http://php.net/user-dir
741 | user_dir =
742 |
743 | ; Directory in which the loadable extensions (modules) reside.
744 | ; http://php.net/extension-dir
745 | ;extension_dir = "./"
746 | ; On windows:
747 | ;extension_dir = "ext"
748 |
749 | ; Directory where the temporary files should be placed.
750 | ; Defaults to the system default (see sys_get_temp_dir)
751 | ;sys_temp_dir = "/tmp"
752 |
753 | ; Whether or not to enable the dl() function. The dl() function does NOT work
754 | ; properly in multithreaded servers, such as IIS or Zeus, and is automatically
755 | ; disabled on them.
756 | ; http://php.net/enable-dl
757 | enable_dl = Off
758 |
759 | ; cgi.force_redirect is necessary to provide security running PHP as a CGI under
760 | ; most web servers. Left undefined, PHP turns this on by default. You can
761 | ; turn it off here AT YOUR OWN RISK
762 | ; **You CAN safely turn this off for IIS, in fact, you MUST.**
763 | ; http://php.net/cgi.force-redirect
764 | ;cgi.force_redirect = 1
765 |
766 | ; if cgi.nph is enabled it will force cgi to always sent Status: 200 with
767 | ; every request. PHP's default behavior is to disable this feature.
768 | ;cgi.nph = 1
769 |
770 | ; if cgi.force_redirect is turned on, and you are not running under Apache or Netscape
771 | ; (iPlanet) web servers, you MAY need to set an environment variable name that PHP
772 | ; will look for to know it is OK to continue execution. Setting this variable MAY
773 | ; cause security issues, KNOW WHAT YOU ARE DOING FIRST.
774 | ; http://php.net/cgi.redirect-status-env
775 | ;cgi.redirect_status_env =
776 |
777 | ; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's
778 | ; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
779 | ; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting
780 | ; this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting
781 | ; of zero causes PHP to behave as before. Default is 1. You should fix your scripts
782 | ; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
783 | ; http://php.net/cgi.fix-pathinfo
784 | ;cgi.fix_pathinfo=1
785 |
786 | ; if cgi.discard_path is enabled, the PHP CGI binary can safely be placed outside
787 | ; of the web tree and people will not be able to circumvent .htaccess security.
788 | ;cgi.discard_path=1
789 |
790 | ; FastCGI under IIS supports the ability to impersonate
791 | ; security tokens of the calling client. This allows IIS to define the
792 | ; security context that the request runs under. mod_fastcgi under Apache
793 | ; does not currently support this feature (03/17/2002)
794 | ; Set to 1 if running under IIS. Default is zero.
795 | ; http://php.net/fastcgi.impersonate
796 | ;fastcgi.impersonate = 1
797 |
798 | ; Disable logging through FastCGI connection. PHP's default behavior is to enable
799 | ; this feature.
800 | ;fastcgi.logging = 0
801 |
802 | ; cgi.rfc2616_headers configuration option tells PHP what type of headers to
803 | ; use when sending HTTP response code. If set to 0, PHP sends Status: header that
804 | ; is supported by Apache. When this option is set to 1, PHP will send
805 | ; RFC2616 compliant header.
806 | ; Default is zero.
807 | ; http://php.net/cgi.rfc2616-headers
808 | ;cgi.rfc2616_headers = 0
809 |
810 | ; cgi.check_shebang_line controls whether CGI PHP checks for line starting with #!
811 | ; (shebang) at the top of the running script. This line might be needed if the
812 | ; script support running both as stand-alone script and via PHP CGI<. PHP in CGI
813 | ; mode skips this line and ignores its content if this directive is turned on.
814 | ; http://php.net/cgi.check-shebang-line
815 | ;cgi.check_shebang_line=1
816 |
817 | ;;;;;;;;;;;;;;;;
818 | ; File Uploads ;
819 | ;;;;;;;;;;;;;;;;
820 |
821 | ; Whether to allow HTTP file uploads.
822 | ; http://php.net/file-uploads
823 | file_uploads = On
824 |
825 | ; Temporary directory for HTTP uploaded files (will use system default if not
826 | ; specified).
827 | ; http://php.net/upload-tmp-dir
828 | ;upload_tmp_dir =
829 |
830 | ; Maximum allowed size for uploaded files.
831 | ; http://php.net/upload-max-filesize
832 | upload_max_filesize = 2M
833 |
834 | ; Maximum number of files that can be uploaded via a single request
835 | max_file_uploads = 20
836 |
837 | ;;;;;;;;;;;;;;;;;;
838 | ; Fopen wrappers ;
839 | ;;;;;;;;;;;;;;;;;;
840 |
841 | ; Whether to allow the treatment of URLs (like http:// or ftp://) as files.
842 | ; http://php.net/allow-url-fopen
843 | allow_url_fopen = On
844 |
845 | ; Whether to allow include/require to open URLs (like http:// or ftp://) as files.
846 | ; http://php.net/allow-url-include
847 | allow_url_include = Off
848 |
849 | ; Define the anonymous ftp password (your email address). PHP's default setting
850 | ; for this is empty.
851 | ; http://php.net/from
852 | ;from="john@doe.com"
853 |
854 | ; Define the User-Agent string. PHP's default setting for this is empty.
855 | ; http://php.net/user-agent
856 | ;user_agent="PHP"
857 |
858 | ; Default timeout for socket based streams (seconds)
859 | ; http://php.net/default-socket-timeout
860 | default_socket_timeout = 60
861 |
862 | ; If your scripts have to deal with files from Macintosh systems,
863 | ; or you are running on a Mac and need to deal with files from
864 | ; unix or win32 systems, setting this flag will cause PHP to
865 | ; automatically detect the EOL character in those files so that
866 | ; fgets() and file() will work regardless of the source of the file.
867 | ; http://php.net/auto-detect-line-endings
868 | ;auto_detect_line_endings = Off
869 |
870 | ;;;;;;;;;;;;;;;;;;;;;;
871 | ; Dynamic Extensions ;
872 | ;;;;;;;;;;;;;;;;;;;;;;
873 |
874 | ; If you wish to have an extension loaded automatically, use the following
875 | ; syntax:
876 | ;
877 | ; extension=modulename
878 | ;
879 | ; For example:
880 | ;
881 | ; extension=mysqli
882 | ;
883 | ; When the extension library to load is not located in the default extension
884 | ; directory, You may specify an absolute path to the library file:
885 | ;
886 | ; extension=/path/to/extension/mysqli.so
887 | ;
888 | ; Note : The syntax used in previous PHP versions ('extension=.so' and
889 | ; 'extension='php_.dll') is supported for legacy reasons and may be
890 | ; deprecated in a future PHP major version. So, when it is possible, please
891 | ; move to the new ('extension=) syntax.
892 | ;
893 | ; Notes for Windows environments :
894 | ;
895 | ; - Many DLL files are located in the extensions/ (PHP 4) or ext/ (PHP 5+)
896 | ; extension folders as well as the separate PECL DLL download (PHP 5+).
897 | ; Be sure to appropriately set the extension_dir directive.
898 | ;
899 | ;extension=bz2
900 | ;extension=curl
901 | ;extension=fileinfo
902 | ;extension=gd2
903 | ;extension=gettext
904 | ;extension=gmp
905 | ;extension=intl
906 | ;extension=imap
907 | ;extension=interbase
908 | ;extension=ldap
909 | ;extension=mbstring
910 | ;extension=exif ; Must be after mbstring as it depends on it
911 | ;extension=mysqli
912 | ;extension=oci8_12c ; Use with Oracle Database 12c Instant Client
913 | ;extension=odbc
914 | ;extension=openssl
915 | ;extension=pdo_firebird
916 | ;extension=pdo_mysql
917 | ;extension=pdo_oci
918 | ;extension=pdo_odbc
919 | ;extension=pdo_pgsql
920 | ;extension=pdo_sqlite
921 | ;extension=pgsql
922 | ;extension=shmop
923 |
924 | ; The MIBS data available in the PHP distribution must be installed.
925 | ; See http://www.php.net/manual/en/snmp.installation.php
926 | ;extension=snmp
927 |
928 | ;extension=soap
929 | ;extension=sockets
930 | ;extension=sodium
931 | ;extension=sqlite3
932 | ;extension=tidy
933 | ;extension=xmlrpc
934 | ;extension=xsl
935 |
936 | ;;;;;;;;;;;;;;;;;;;
937 | ; Module Settings ;
938 | ;;;;;;;;;;;;;;;;;;;
939 |
940 | [CLI Server]
941 | ; Whether the CLI web server uses ANSI color coding in its terminal output.
942 | cli_server.color = On
943 |
944 | [Date]
945 | ; Defines the default timezone used by the date functions
946 | ; http://php.net/date.timezone
947 | ;date.timezone =
948 |
949 | ; http://php.net/date.default-latitude
950 | ;date.default_latitude = 31.7667
951 |
952 | ; http://php.net/date.default-longitude
953 | ;date.default_longitude = 35.2333
954 |
955 | ; http://php.net/date.sunrise-zenith
956 | ;date.sunrise_zenith = 90.583333
957 |
958 | ; http://php.net/date.sunset-zenith
959 | ;date.sunset_zenith = 90.583333
960 |
961 | [filter]
962 | ; http://php.net/filter.default
963 | ;filter.default = unsafe_raw
964 |
965 | ; http://php.net/filter.default-flags
966 | ;filter.default_flags =
967 |
968 | [iconv]
969 | ; Use of this INI entry is deprecated, use global input_encoding instead.
970 | ; If empty, default_charset or input_encoding or iconv.input_encoding is used.
971 | ; The precedence is: default_charset < input_encoding < iconv.input_encoding
972 | ;iconv.input_encoding =
973 |
974 | ; Use of this INI entry is deprecated, use global internal_encoding instead.
975 | ; If empty, default_charset or internal_encoding or iconv.internal_encoding is used.
976 | ; The precedence is: default_charset < internal_encoding < iconv.internal_encoding
977 | ;iconv.internal_encoding =
978 |
979 | ; Use of this INI entry is deprecated, use global output_encoding instead.
980 | ; If empty, default_charset or output_encoding or iconv.output_encoding is used.
981 | ; The precedence is: default_charset < output_encoding < iconv.output_encoding
982 | ; To use an output encoding conversion, iconv's output handler must be set
983 | ; otherwise output encoding conversion cannot be performed.
984 | ;iconv.output_encoding =
985 |
986 | [intl]
987 | ;intl.default_locale =
988 | ; This directive allows you to produce PHP errors when some error
989 | ; happens within intl functions. The value is the level of the error produced.
990 | ; Default is 0, which does not produce any errors.
991 | ;intl.error_level = E_WARNING
992 | ;intl.use_exceptions = 0
993 |
994 | [sqlite3]
995 | ;sqlite3.extension_dir =
996 |
997 | [Pcre]
998 | ; PCRE library backtracking limit.
999 | ; http://php.net/pcre.backtrack-limit
1000 | ;pcre.backtrack_limit=100000
1001 |
1002 | ; PCRE library recursion limit.
1003 | ; Please note that if you set this value to a high number you may consume all
1004 | ; the available process stack and eventually crash PHP (due to reaching the
1005 | ; stack size limit imposed by the Operating System).
1006 | ; http://php.net/pcre.recursion-limit
1007 | ;pcre.recursion_limit=100000
1008 |
1009 | ; Enables or disables JIT compilation of patterns. This requires the PCRE
1010 | ; library to be compiled with JIT support.
1011 | ;pcre.jit=1
1012 |
1013 | [Pdo]
1014 | ; Whether to pool ODBC connections. Can be one of "strict", "relaxed" or "off"
1015 | ; http://php.net/pdo-odbc.connection-pooling
1016 | ;pdo_odbc.connection_pooling=strict
1017 |
1018 | ;pdo_odbc.db2_instance_name
1019 |
1020 | [Pdo_mysql]
1021 | ; Default socket name for local MySQL connects. If empty, uses the built-in
1022 | ; MySQL defaults.
1023 | pdo_mysql.default_socket=
1024 |
1025 | [Phar]
1026 | ; http://php.net/phar.readonly
1027 | ;phar.readonly = On
1028 |
1029 | ; http://php.net/phar.require-hash
1030 | ;phar.require_hash = On
1031 |
1032 | ;phar.cache_list =
1033 |
1034 | [mail function]
1035 | ; For Win32 only.
1036 | ; http://php.net/smtp
1037 | SMTP = localhost
1038 | ; http://php.net/smtp-port
1039 | smtp_port = 25
1040 |
1041 | ; For Win32 only.
1042 | ; http://php.net/sendmail-from
1043 | ;sendmail_from = me@example.com
1044 |
1045 | ; For Unix only. You may supply arguments as well (default: "sendmail -t -i").
1046 | ; http://php.net/sendmail-path
1047 | ;sendmail_path =
1048 |
1049 | ; Force the addition of the specified parameters to be passed as extra parameters
1050 | ; to the sendmail binary. These parameters will always replace the value of
1051 | ; the 5th parameter to mail().
1052 | ;mail.force_extra_parameters =
1053 |
1054 | ; Add X-PHP-Originating-Script: that will include uid of the script followed by the filename
1055 | mail.add_x_header = Off
1056 |
1057 | ; The path to a log file that will log all mail() calls. Log entries include
1058 | ; the full path of the script, line number, To address and headers.
1059 | ;mail.log =
1060 | ; Log mail to syslog (Event Log on Windows).
1061 | ;mail.log = syslog
1062 |
1063 | [ODBC]
1064 | ; http://php.net/odbc.default-db
1065 | ;odbc.default_db = Not yet implemented
1066 |
1067 | ; http://php.net/odbc.default-user
1068 | ;odbc.default_user = Not yet implemented
1069 |
1070 | ; http://php.net/odbc.default-pw
1071 | ;odbc.default_pw = Not yet implemented
1072 |
1073 | ; Controls the ODBC cursor model.
1074 | ; Default: SQL_CURSOR_STATIC (default).
1075 | ;odbc.default_cursortype
1076 |
1077 | ; Allow or prevent persistent links.
1078 | ; http://php.net/odbc.allow-persistent
1079 | odbc.allow_persistent = On
1080 |
1081 | ; Check that a connection is still valid before reuse.
1082 | ; http://php.net/odbc.check-persistent
1083 | odbc.check_persistent = On
1084 |
1085 | ; Maximum number of persistent links. -1 means no limit.
1086 | ; http://php.net/odbc.max-persistent
1087 | odbc.max_persistent = -1
1088 |
1089 | ; Maximum number of links (persistent + non-persistent). -1 means no limit.
1090 | ; http://php.net/odbc.max-links
1091 | odbc.max_links = -1
1092 |
1093 | ; Handling of LONG fields. Returns number of bytes to variables. 0 means
1094 | ; passthru.
1095 | ; http://php.net/odbc.defaultlrl
1096 | odbc.defaultlrl = 4096
1097 |
1098 | ; Handling of binary data. 0 means passthru, 1 return as is, 2 convert to char.
1099 | ; See the documentation on odbc_binmode and odbc_longreadlen for an explanation
1100 | ; of odbc.defaultlrl and odbc.defaultbinmode
1101 | ; http://php.net/odbc.defaultbinmode
1102 | odbc.defaultbinmode = 1
1103 |
1104 | [Interbase]
1105 | ; Allow or prevent persistent links.
1106 | ibase.allow_persistent = 1
1107 |
1108 | ; Maximum number of persistent links. -1 means no limit.
1109 | ibase.max_persistent = -1
1110 |
1111 | ; Maximum number of links (persistent + non-persistent). -1 means no limit.
1112 | ibase.max_links = -1
1113 |
1114 | ; Default database name for ibase_connect().
1115 | ;ibase.default_db =
1116 |
1117 | ; Default username for ibase_connect().
1118 | ;ibase.default_user =
1119 |
1120 | ; Default password for ibase_connect().
1121 | ;ibase.default_password =
1122 |
1123 | ; Default charset for ibase_connect().
1124 | ;ibase.default_charset =
1125 |
1126 | ; Default timestamp format.
1127 | ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
1128 |
1129 | ; Default date format.
1130 | ibase.dateformat = "%Y-%m-%d"
1131 |
1132 | ; Default time format.
1133 | ibase.timeformat = "%H:%M:%S"
1134 |
1135 | [MySQLi]
1136 |
1137 | ; Maximum number of persistent links. -1 means no limit.
1138 | ; http://php.net/mysqli.max-persistent
1139 | mysqli.max_persistent = -1
1140 |
1141 | ; Allow accessing, from PHP's perspective, local files with LOAD DATA statements
1142 | ; http://php.net/mysqli.allow_local_infile
1143 | ;mysqli.allow_local_infile = On
1144 |
1145 | ; Allow or prevent persistent links.
1146 | ; http://php.net/mysqli.allow-persistent
1147 | mysqli.allow_persistent = On
1148 |
1149 | ; Maximum number of links. -1 means no limit.
1150 | ; http://php.net/mysqli.max-links
1151 | mysqli.max_links = -1
1152 |
1153 | ; Default port number for mysqli_connect(). If unset, mysqli_connect() will use
1154 | ; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the
1155 | ; compile-time value defined MYSQL_PORT (in that order). Win32 will only look
1156 | ; at MYSQL_PORT.
1157 | ; http://php.net/mysqli.default-port
1158 | mysqli.default_port = 3306
1159 |
1160 | ; Default socket name for local MySQL connects. If empty, uses the built-in
1161 | ; MySQL defaults.
1162 | ; http://php.net/mysqli.default-socket
1163 | mysqli.default_socket =
1164 |
1165 | ; Default host for mysql_connect() (doesn't apply in safe mode).
1166 | ; http://php.net/mysqli.default-host
1167 | mysqli.default_host =
1168 |
1169 | ; Default user for mysql_connect() (doesn't apply in safe mode).
1170 | ; http://php.net/mysqli.default-user
1171 | mysqli.default_user =
1172 |
1173 | ; Default password for mysqli_connect() (doesn't apply in safe mode).
1174 | ; Note that this is generally a *bad* idea to store passwords in this file.
1175 | ; *Any* user with PHP access can run 'echo get_cfg_var("mysqli.default_pw")
1176 | ; and reveal this password! And of course, any users with read access to this
1177 | ; file will be able to reveal the password as well.
1178 | ; http://php.net/mysqli.default-pw
1179 | mysqli.default_pw =
1180 |
1181 | ; Allow or prevent reconnect
1182 | mysqli.reconnect = Off
1183 |
1184 | [mysqlnd]
1185 | ; Enable / Disable collection of general statistics by mysqlnd which can be
1186 | ; used to tune and monitor MySQL operations.
1187 | mysqlnd.collect_statistics = On
1188 |
1189 | ; Enable / Disable collection of memory usage statistics by mysqlnd which can be
1190 | ; used to tune and monitor MySQL operations.
1191 | mysqlnd.collect_memory_statistics = Off
1192 |
1193 | ; Records communication from all extensions using mysqlnd to the specified log
1194 | ; file.
1195 | ; http://php.net/mysqlnd.debug
1196 | ;mysqlnd.debug =
1197 |
1198 | ; Defines which queries will be logged.
1199 | ;mysqlnd.log_mask = 0
1200 |
1201 | ; Default size of the mysqlnd memory pool, which is used by result sets.
1202 | ;mysqlnd.mempool_default_size = 16000
1203 |
1204 | ; Size of a pre-allocated buffer used when sending commands to MySQL in bytes.
1205 | ;mysqlnd.net_cmd_buffer_size = 2048
1206 |
1207 | ; Size of a pre-allocated buffer used for reading data sent by the server in
1208 | ; bytes.
1209 | ;mysqlnd.net_read_buffer_size = 32768
1210 |
1211 | ; Timeout for network requests in seconds.
1212 | ;mysqlnd.net_read_timeout = 31536000
1213 |
1214 | ; SHA-256 Authentication Plugin related. File with the MySQL server public RSA
1215 | ; key.
1216 | ;mysqlnd.sha256_server_public_key =
1217 |
1218 | [OCI8]
1219 |
1220 | ; Connection: Enables privileged connections using external
1221 | ; credentials (OCI_SYSOPER, OCI_SYSDBA)
1222 | ; http://php.net/oci8.privileged-connect
1223 | ;oci8.privileged_connect = Off
1224 |
1225 | ; Connection: The maximum number of persistent OCI8 connections per
1226 | ; process. Using -1 means no limit.
1227 | ; http://php.net/oci8.max-persistent
1228 | ;oci8.max_persistent = -1
1229 |
1230 | ; Connection: The maximum number of seconds a process is allowed to
1231 | ; maintain an idle persistent connection. Using -1 means idle
1232 | ; persistent connections will be maintained forever.
1233 | ; http://php.net/oci8.persistent-timeout
1234 | ;oci8.persistent_timeout = -1
1235 |
1236 | ; Connection: The number of seconds that must pass before issuing a
1237 | ; ping during oci_pconnect() to check the connection validity. When
1238 | ; set to 0, each oci_pconnect() will cause a ping. Using -1 disables
1239 | ; pings completely.
1240 | ; http://php.net/oci8.ping-interval
1241 | ;oci8.ping_interval = 60
1242 |
1243 | ; Connection: Set this to a user chosen connection class to be used
1244 | ; for all pooled server requests with Oracle 11g Database Resident
1245 | ; Connection Pooling (DRCP). To use DRCP, this value should be set to
1246 | ; the same string for all web servers running the same application,
1247 | ; the database pool must be configured, and the connection string must
1248 | ; specify to use a pooled server.
1249 | ;oci8.connection_class =
1250 |
1251 | ; High Availability: Using On lets PHP receive Fast Application
1252 | ; Notification (FAN) events generated when a database node fails. The
1253 | ; database must also be configured to post FAN events.
1254 | ;oci8.events = Off
1255 |
1256 | ; Tuning: This option enables statement caching, and specifies how
1257 | ; many statements to cache. Using 0 disables statement caching.
1258 | ; http://php.net/oci8.statement-cache-size
1259 | ;oci8.statement_cache_size = 20
1260 |
1261 | ; Tuning: Enables statement prefetching and sets the default number of
1262 | ; rows that will be fetched automatically after statement execution.
1263 | ; http://php.net/oci8.default-prefetch
1264 | ;oci8.default_prefetch = 100
1265 |
1266 | ; Compatibility. Using On means oci_close() will not close
1267 | ; oci_connect() and oci_new_connect() connections.
1268 | ; http://php.net/oci8.old-oci-close-semantics
1269 | ;oci8.old_oci_close_semantics = Off
1270 |
1271 | [PostgreSQL]
1272 | ; Allow or prevent persistent links.
1273 | ; http://php.net/pgsql.allow-persistent
1274 | pgsql.allow_persistent = On
1275 |
1276 | ; Detect broken persistent links always with pg_pconnect().
1277 | ; Auto reset feature requires a little overheads.
1278 | ; http://php.net/pgsql.auto-reset-persistent
1279 | pgsql.auto_reset_persistent = Off
1280 |
1281 | ; Maximum number of persistent links. -1 means no limit.
1282 | ; http://php.net/pgsql.max-persistent
1283 | pgsql.max_persistent = -1
1284 |
1285 | ; Maximum number of links (persistent+non persistent). -1 means no limit.
1286 | ; http://php.net/pgsql.max-links
1287 | pgsql.max_links = -1
1288 |
1289 | ; Ignore PostgreSQL backends Notice message or not.
1290 | ; Notice message logging require a little overheads.
1291 | ; http://php.net/pgsql.ignore-notice
1292 | pgsql.ignore_notice = 0
1293 |
1294 | ; Log PostgreSQL backends Notice message or not.
1295 | ; Unless pgsql.ignore_notice=0, module cannot log notice message.
1296 | ; http://php.net/pgsql.log-notice
1297 | pgsql.log_notice = 0
1298 |
1299 | [bcmath]
1300 | ; Number of decimal digits for all bcmath functions.
1301 | ; http://php.net/bcmath.scale
1302 | bcmath.scale = 0
1303 |
1304 | [browscap]
1305 | ; http://php.net/browscap
1306 | ;browscap = extra/browscap.ini
1307 |
1308 | [Session]
1309 | ; Handler used to store/retrieve data.
1310 | ; http://php.net/session.save-handler
1311 | session.save_handler = files
1312 |
1313 | ; Argument passed to save_handler. In the case of files, this is the path
1314 | ; where data files are stored. Note: Windows users have to change this
1315 | ; variable in order to use PHP's session functions.
1316 | ;
1317 | ; The path can be defined as:
1318 | ;
1319 | ; session.save_path = "N;/path"
1320 | ;
1321 | ; where N is an integer. Instead of storing all the session files in
1322 | ; /path, what this will do is use subdirectories N-levels deep, and
1323 | ; store the session data in those directories. This is useful if
1324 | ; your OS has problems with many files in one directory, and is
1325 | ; a more efficient layout for servers that handle many sessions.
1326 | ;
1327 | ; NOTE 1: PHP will not create this directory structure automatically.
1328 | ; You can use the script in the ext/session dir for that purpose.
1329 | ; NOTE 2: See the section on garbage collection below if you choose to
1330 | ; use subdirectories for session storage
1331 | ;
1332 | ; The file storage module creates files using mode 600 by default.
1333 | ; You can change that by using
1334 | ;
1335 | ; session.save_path = "N;MODE;/path"
1336 | ;
1337 | ; where MODE is the octal representation of the mode. Note that this
1338 | ; does not overwrite the process's umask.
1339 | ; http://php.net/session.save-path
1340 | ;session.save_path = "/var/lib/php/sessions"
1341 |
1342 | ; Whether to use strict session mode.
1343 | ; Strict session mode does not accept an uninitialized session ID, and
1344 | ; regenerates the session ID if the browser sends an uninitialized session ID.
1345 | ; Strict mode protects applications from session fixation via a session adoption
1346 | ; vulnerability. It is disabled by default for maximum compatibility, but
1347 | ; enabling it is encouraged.
1348 | ; https://wiki.php.net/rfc/strict_sessions
1349 | session.use_strict_mode = 0
1350 |
1351 | ; Whether to use cookies.
1352 | ; http://php.net/session.use-cookies
1353 | session.use_cookies = 1
1354 |
1355 | ; http://php.net/session.cookie-secure
1356 | ;session.cookie_secure =
1357 |
1358 | ; This option forces PHP to fetch and use a cookie for storing and maintaining
1359 | ; the session id. We encourage this operation as it's very helpful in combating
1360 | ; session hijacking when not specifying and managing your own session id. It is
1361 | ; not the be-all and end-all of session hijacking defense, but it's a good start.
1362 | ; http://php.net/session.use-only-cookies
1363 | session.use_only_cookies = 1
1364 |
1365 | ; Name of the session (used as cookie name).
1366 | ; http://php.net/session.name
1367 | session.name = PHPSESSID
1368 |
1369 | ; Initialize session on request startup.
1370 | ; http://php.net/session.auto-start
1371 | session.auto_start = 0
1372 |
1373 | ; Lifetime in seconds of cookie or, if 0, until browser is restarted.
1374 | ; http://php.net/session.cookie-lifetime
1375 | session.cookie_lifetime = 0
1376 |
1377 | ; The path for which the cookie is valid.
1378 | ; http://php.net/session.cookie-path
1379 | session.cookie_path = /
1380 |
1381 | ; The domain for which the cookie is valid.
1382 | ; http://php.net/session.cookie-domain
1383 | session.cookie_domain =
1384 |
1385 | ; Whether or not to add the httpOnly flag to the cookie, which makes it
1386 | ; inaccessible to browser scripting languages such as JavaScript.
1387 | ; http://php.net/session.cookie-httponly
1388 | session.cookie_httponly =
1389 |
1390 | ; Handler used to serialize data. php is the standard serializer of PHP.
1391 | ; http://php.net/session.serialize-handler
1392 | session.serialize_handler = php
1393 |
1394 | ; Defines the probability that the 'garbage collection' process is started
1395 | ; on every session initialization. The probability is calculated by using
1396 | ; gc_probability/gc_divisor. Where session.gc_probability is the numerator
1397 | ; and gc_divisor is the denominator in the equation. Setting this value to 1
1398 | ; when the session.gc_divisor value is 100 will give you approximately a 1% chance
1399 | ; the gc will run on any given request.
1400 | ; Default Value: 1
1401 | ; Development Value: 1
1402 | ; Production Value: 1
1403 | ; http://php.net/session.gc-probability
1404 | session.gc_probability = 0
1405 |
1406 | ; Defines the probability that the 'garbage collection' process is started on every
1407 | ; session initialization. The probability is calculated by using the following equation:
1408 | ; gc_probability/gc_divisor. Where session.gc_probability is the numerator and
1409 | ; session.gc_divisor is the denominator in the equation. Setting this value to 100
1410 | ; when the session.gc_probability value is 1 will give you approximately a 1% chance
1411 | ; the gc will run on any given request. Increasing this value to 1000 will give you
1412 | ; a 0.1% chance the gc will run on any given request. For high volume production servers,
1413 | ; this is a more efficient approach.
1414 | ; Default Value: 100
1415 | ; Development Value: 1000
1416 | ; Production Value: 1000
1417 | ; http://php.net/session.gc-divisor
1418 | session.gc_divisor = 1000
1419 |
1420 | ; After this number of seconds, stored data will be seen as 'garbage' and
1421 | ; cleaned up by the garbage collection process.
1422 | ; http://php.net/session.gc-maxlifetime
1423 | session.gc_maxlifetime = 1440
1424 |
1425 | ; NOTE: If you are using the subdirectory option for storing session files
1426 | ; (see session.save_path above), then garbage collection does *not*
1427 | ; happen automatically. You will need to do your own garbage
1428 | ; collection through a shell script, cron entry, or some other method.
1429 | ; For example, the following script would is the equivalent of
1430 | ; setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes):
1431 | ; find /path/to/sessions -cmin +24 -type f | xargs rm
1432 |
1433 | ; Check HTTP Referer to invalidate externally stored URLs containing ids.
1434 | ; HTTP_REFERER has to contain this substring for the session to be
1435 | ; considered as valid.
1436 | ; http://php.net/session.referer-check
1437 | session.referer_check =
1438 |
1439 | ; Set to {nocache,private,public,} to determine HTTP caching aspects
1440 | ; or leave this empty to avoid sending anti-caching headers.
1441 | ; http://php.net/session.cache-limiter
1442 | session.cache_limiter = nocache
1443 |
1444 | ; Document expires after n minutes.
1445 | ; http://php.net/session.cache-expire
1446 | session.cache_expire = 180
1447 |
1448 | ; trans sid support is disabled by default.
1449 | ; Use of trans sid may risk your users' security.
1450 | ; Use this option with caution.
1451 | ; - User may send URL contains active session ID
1452 | ; to other person via. email/irc/etc.
1453 | ; - URL that contains active session ID may be stored
1454 | ; in publicly accessible computer.
1455 | ; - User may access your site with the same session ID
1456 | ; always using URL stored in browser's history or bookmarks.
1457 | ; http://php.net/session.use-trans-sid
1458 | session.use_trans_sid = 0
1459 |
1460 | ; Set session ID character length. This value could be between 22 to 256.
1461 | ; Shorter length than default is supported only for compatibility reason.
1462 | ; Users should use 32 or more chars.
1463 | ; http://php.net/session.sid-length
1464 | ; Default Value: 32
1465 | ; Development Value: 26
1466 | ; Production Value: 26
1467 | session.sid_length = 26
1468 |
1469 | ; The URL rewriter will look for URLs in a defined set of HTML tags.
1470 | ;