Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PHP] Allow additional php.ini files instead of overwriting via options.file #969

Closed
ruudk opened this issue Oct 7, 2023 · 5 comments
Closed
Labels
z-documentation-update-needed This type of issues likely have a link to an issue in the Unit Docs repo

Comments

@ruudk
Copy link

ruudk commented Oct 7, 2023

Currently, there is no way to load additional php.ini files.

When you specify options.file, you override the default loaded php.ini completely.

{
  "applications": {
    "hello-world": {
      "type": "php",
      "root": "/www/public",
      "script": "index.php",
      "options": {
        "file": "some-tweaks.ini"
      }
    }
  }
}

When reading the code, it seems this is how it was designed:

unit/src/nxt_php_sapi.c

Lines 409 to 422 in c905d0d

if (c->options != NULL) {
value = nxt_conf_get_object_member(c->options, &file_str, NULL);
if (value != NULL) {
nxt_conf_get_string(value, &ini_path);
ret = nxt_php_set_ini_path(task, &ini_path,
conf->working_directory);
if (nxt_slow_path(ret != NXT_OK)) {
return NXT_ERROR;
}
}
}

nxt_php_sapi_module.php_ini_path_override = (char *) start;

But, if you want to enable (zend) extensions on a per application basis, this becomes annoying.

You now have to copy the default php.ini, store it in a new file and then append your tweaks to it.

It would be easier if I could do this:

{
  "applications": {
    "hello-world": {
      "type": "php",
      "root": "/www/public",
      "script": "index.php",
      "options": {
        "additional-files": ["some-tweaks.ini"]
      }
    }
  }
}

Or, specify the (additional) extensions that I want to load and let me provide extra config via admin and user:

{
  "applications": {
    "hello-world": {
      "type": "php",
      "root": "/www/public",
      "script": "index.php",
      "options": {
        "extensions": [],
        "zend_extensions": ["xdebug.so"],
        "admin": {
          "xdebug.mode": "debug",
          "xdebug.start_with_request": "trigger",
          "xdebug.client_host": "127.0.0.1",
          "xdebug.idekey": "PHPSTORM"
        }
      }
    }
  }
}
@lcrilly
Copy link
Contributor

lcrilly commented Oct 10, 2023

Thanks for sharing this use case. If the options/file value was an array of filenames, would that meet your needs? Something like this:

{
  "applications": {
    "hello-world": {
      "type": "php",
      "root": "/www/public",
      "script": "index.php",
      "options": {
        "file": [
            "php.ini",
            "some-tweaks.ini"
        ]
      }
    }
  }
}

@lcrilly lcrilly added the z-enhancement ⬆️ Product Enhancement label Oct 10, 2023
@ruudk
Copy link
Author

ruudk commented Oct 10, 2023

That would be perfect!

@ac000
Copy link
Member

ac000 commented Oct 11, 2023

I'm not sure that we can make options.file an array as we can only really set nxt_php_sapi_module.php_ini_path_override once.

nxt_php_sapi_module aka sapi_module_struct is a structure used to pass various bits of config to PHP and php_ini_path_override simply points to a file or directory path.

@ruudk

AFAICT you have two options

  1. Put any additional ini files you wanted loaded in the PHP_CONFIG_FILE_SCAN_DIR/--with-config-file-scan-dir directory, e.g /etc/php.d

  2. Set the PHP_INI_SCAN_DIR environment variable to point to an alternate directory to scan for ini files (it will still load /etc/php.ini) . E.g

{
    "applications": {
        "hello-world": {
            "type": "php",
            "root": "/www/public",
            "script": "index.php",
            "environment": {
                "PHP_INI_SCAN_DIR": "/tmp/php.inis"
            }
        }
    }
}

@tippexs
Copy link
Contributor

tippexs commented Oct 11, 2023

I think the environment variable is a good solution. The tweaked php.ini files can be placed somewhere and loaded dynamically. After checking the docs again, this option can even be used to set multiple directories separated by comma. I will give it a try but from what it looks like this should be something we put in our PHP docs to share this option with others.

@ruudk
Copy link
Author

ruudk commented Oct 11, 2023

Thanks for the suggestions. I didn't think about using the PHP_INI_SCAN_DIR here!

It works!

{
  "applications": {
    "app": {
      "type": "php",
      "root": "public",
      "script": "index.php",
      "environment": {
          "PHP_INI_SCAN_DIR": ":config/"
      }
    }
}

Because PHP_INI_SCAN_DIR starts with :, this loads the default php.ini and the default scanned files, plus loads additional php.ini in the config directory. The directory can be a relative or absolute path.

If you want to dynamically load Xdebug depending on the ?XDEBUG_TRIGGER=1 value, you can do this:

{
  "settings": {
    "http": {
      "log_route": true
    }
  },
  "listeners": {
    "*:443": {
      "pass": "routes/https",
      "tls": {
        "certificate": "bundle"
      }
    }
  },
  "routes": {
    "https": [
      {
        "match": {
          "arguments": {
              "XDEBUG_TRIGGER": "1"
          }
        },
        "action": {
            "pass": "applications/app-xdebug",
            "response_headers": {
                "With-Xdebug": "true"
            }
        }
      },
      {
        "action": {
          "pass": "applications/app",
            "response_headers": {
                "With-Xdebug": "false"
            }
        }
      }
    ]
  },
  "applications": {
    "app": {
      "type": "php",
      "root": "public",
      "script": "index.php"
    },
    "app-xdebug": {
      "type": "php",
      "root": "public",
      "script": "index.php",
      "environment": {
        "PHP_INI_SCAN_DIR": ":config/directory-that-has-an-ini-file-that-enables-xdebug/"
      }
    }
  }
}

Thanks all!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
z-documentation-update-needed This type of issues likely have a link to an issue in the Unit Docs repo
Projects
None yet
Development

No branches or pull requests

4 participants