Minimalno (da radi)

  • WordPress: 6.8+
  • WooCommerce (ako je WC plugin): 8.0+
  • PHP: 8.1+, idealno 8.2/8.3
  • MySQL: 8.0+ ili MariaDB 10.3+
  • HTTPS: obavezno (Let’s Encrypt ili slično)
  • Outbound SMTP ili WP mail radi (server mora da može da šalje mail: wp_mail()), ili da korisnik ima SMTP plugin
  • Cron / WP-Cron: uključen
  • PHPBolt Loader PHP ekstenzija mora biti instalirana i učitana za PHP verziju na kojoj radi sajt.

Preporučeno

  • PHP memory_limit: 256MB+ (minimum 128MB)
  • max_execution_time: 60s+ (minimum 30s)
  • upload_max_filesize / post_max_size: 32MB+ (minimum 16MB)
  • allow_url_fopen: On (ako plugin vuče remote fajlove)
  • cURL extension: obavezno
  • OpenSSL extension: obavezno (HTTPS/TLS)
  • JSON extension: obavezno
  • mbstring: preporučeno (srpski, unicode, normalno parsiranje)
  • DOM/XML: preporučeno (ako ima XML/HTML parsiranje)
  • Intl: preporučeno (formatiranje valuta/datuma, lokalizacija)

Debug

Ako niste sigurni da li vam podrzava hosting, otvorite fajl nazvan info.php i ubacite sledeci sadrzaj ispod i sacuvajte potom otvorite vasdomen.tld/info.php

<?php
declare(strict_types=1);

header('Content-Type: text/plain; charset=utf-8');

function bytes_from_ini(string $val): int {
    $val = trim($val);
    if ($val === '' || $val === '-1') return -1; // unlimited
    $last = strtolower($val[strlen($val)-1]);
    $num = (float)$val;

    switch ($last) {
        case 'g': return (int)($num * 1024 * 1024 * 1024);
        case 'm': return (int)($num * 1024 * 1024);
        case 'k': return (int)($num * 1024);
        default:  return (int)$num;
    }
}

function fmt_bytes(int $b): string {
    if ($b < 0) return 'unlimited';
    $units = ['B','KB','MB','GB','TB'];
    $i = 0;
    $v = (float)$b;
    while ($v >= 1024 && $i < count($units)-1) {
        $v /= 1024;
        $i++;
    }
    return rtrim(rtrim(number_format($v, 2, '.', ''), '0'), '.') . $units[$i];
}

function ok(bool $pass): string {
    return $pass ? 'OK' : 'FAIL';
}

echo "=== PHP Environment Check ===\n";
echo "PHP_VERSION=" . PHP_VERSION . "\n";
echo "SAPI=" . php_sapi_name() . "\n";
echo "Loaded php.ini=" . (php_ini_loaded_file() ?: 'NONE') . "\n";
echo "Scanned INIs=" . (php_ini_scanned_files() ?: 'NONE') . "\n\n";

/** Requirements */
$req = [
    [
        'name' => 'memory_limit',
        'type' => 'ini_bytes',
        'min'  => 128 * 1024 * 1024,
        'good' => 256 * 1024 * 1024,
        'note' => 'PHP memory_limit: 256MB+ (minimum 128MB)',
    ],
    [
        'name' => 'max_execution_time',
        'type' => 'ini_int',
        'min'  => 30,
        'good' => 60,
        'note' => 'max_execution_time: 60s+ (minimum 30s)',
    ],
    [
        'name' => 'upload_max_filesize',
        'type' => 'ini_bytes',
        'min'  => 16 * 1024 * 1024,
        'good' => 32 * 1024 * 1024,
        'note' => 'upload_max_filesize: 32MB+ (minimum 16MB)',
    ],
    [
        'name' => 'post_max_size',
        'type' => 'ini_bytes',
        'min'  => 16 * 1024 * 1024,
        'good' => 32 * 1024 * 1024,
        'note' => 'post_max_size: 32MB+ (minimum 16MB)',
    ],
    [
        'name' => 'allow_url_fopen',
        'type' => 'ini_bool_on',
        'min'  => true,
        'good' => true,
        'note' => 'allow_url_fopen: On (ako plugin vuče remote fajlove)',
    ],
];

echo "--- INI settings ---\n";
foreach ($req as $r) {
    $name = $r['name'];
    $raw  = ini_get($name);

    if ($r['type'] === 'ini_bytes') {
        $val = bytes_from_ini((string)$raw);
        $pass = ($val < 0) ? true : ($val >= (int)$r['min']);
        $isGood = ($val < 0) ? true : ($val >= (int)$r['good']);
        echo sprintf(
            "%-22s = %-10s  [%s]  (%s)\n",
            $name,
            $raw === '' ? 'N/A' : ($val < 0 ? 'unlimited' : fmt_bytes($val)),
            ok($pass),
            $isGood ? "preporuceno odgovara" : "nije u skladu sa preporukom"
        );
        continue;
    }

    if ($r['type'] === 'ini_int') {
        $val = (int)$raw;
        $pass = ($val >= (int)$r['min']);
        $isGood = ($val >= (int)$r['good']);
        echo sprintf(
            "%-22s = %-10s  [%s]  (%s)\n",
            $name,
            (string)$val,
            ok($pass),
            $isGood ? "preporuceno odgovara" : "nije u skladu sa preporukom"
        );
        continue;
    }

    if ($r['type'] === 'ini_bool_on') {
        $val = filter_var($raw, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
        // ini_get sometimes returns "1"/"0" or "On"/"Off"
        $val = ($raw === false) ? null : ($raw === '1' || strtolower((string)$raw) === 'on' ? true : ($raw === '0' || strtolower((string)$raw) === 'off' ? false : $val));
        $pass = ($val === true);
        echo sprintf(
            "%-22s = %-10s  [%s]\n",
            $name,
            ($val === null ? 'N/A' : ($val ? 'On' : 'Off')),
            ok($pass)
        );
        continue;
    }
}
echo "\n";

/** Extensions */
$extensions = [
    ['name' => 'curl',      'required' => true,  'note' => 'cURL extension: obavezno'],
    ['name' => 'openssl',   'required' => true,  'note' => 'OpenSSL extension: obavezno (HTTPS/TLS)'],
    ['name' => 'json',      'required' => true,  'note' => 'JSON extension: obavezno'],
    ['name' => 'mbstring',  'required' => false, 'note' => 'mbstring: preporučeno'],
    ['name' => 'dom',       'required' => false, 'note' => 'DOM/XML: preporučeno (DOM)'],
    ['name' => 'xml',       'required' => false, 'note' => 'DOM/XML: preporučeno (XML)'],
    ['name' => 'intl',      'required' => false, 'note' => 'Intl: preporučeno'],
];

echo "--- Extensions ---\n";
foreach ($extensions as $e) {
    $loaded = extension_loaded($e['name']);
    $status = $loaded ? 'OK' : ($e['required'] ? 'FAIL' : 'WARN');
    echo sprintf("%-10s : %-4s  (%s)\n", $e['name'], $status, $e['note']);
}