Устраняем ошибку Joomla (Failed to start the session already started by PHP ($_SESSION is set))

Блог - PROMO64

fix для ошибки Joomla (Failed to start the session already started by PHP ($_SESSION is set))

Меняем содержимое файла — корень-сайта/libraries/joomla/session/handler/native.php

<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Session
 *
 * @copyright   Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */
defined('JPATH_PLATFORM') or die;
/**
 * Interface for managing HTTP sessions
 *
 * @since  3.5
 */
class JSessionHandlerNative implements JSessionHandlerInterface
{
  /**
   * Has the session been started
   *
   * @var    boolean
   * @since  3.5
   */
  private $started = false;
  /**
   * Has the session been closed
   *
   * @var    boolean
   * @since  3.5
   */
  private $closed = false;
  /**
   * Starts the session
   *
   * @return  boolean  True if started
   *
   * @since   3.5
   */
  public function start()
  {
    if ($this->isStarted())
    {
      return true;
    }
    $this->doSessionStart();
    return true;
  }
  /**
   * Checks if the session is started.
   *
   * @return  boolean  True if started, false otherwise.
   *
   * @since   3.5
   */
  public function isStarted()
  {
    return $this->started;
  }
  /**
   * Returns the session ID
   *
   * @return  string  The session ID
   *
   * @since   3.5
   */
  public function getId()
  {
    return session_id();
  }
  /**
   * Sets the session ID
   *
   * @param   string  $id  The session ID
   *
   * @return  void
   *
   * @since   3.5
   * @throws  LogicException
   */
  public function setId($id)
  {
    if ($this->isStarted())
    {
      throw new LogicException('Cannot change the ID of an active session');
    }
    session_id($id);
  }
  /**
   * Returns the session name
   *
   * @return  mixed  The session name
   *
   * @since   3.5
   */
  public function getName()
  {
    return session_name();
  }
  /**
   * Sets the session name
   *
   * @param   string  $name  The name of the session
   *
   * @return  void
   *
   * @since   3.5
   * @throws  LogicException
   */
  public function setName($name)
  {
    if ($this->isStarted())
    {
      throw new LogicException('Cannot change the name of an active session');
    }
    session_name($name);
  }
  /**
   * Regenerates ID that represents this storage.
   *
   * Note regenerate+destroy should not clear the session data in memory only delete the session data from persistent storage.
   *
   * @param   boolean  $destroy   Destroy session when regenerating?
   * @param   integer  $lifetime  Sets the cookie lifetime for the session cookie. A null value will leave the system settings unchanged,
   *                              0 sets the cookie to expire with browser session. Time is in seconds, and is not a Unix timestamp.
   *
   * @return  boolean  True if session regenerated, false if error
   *
   * @since   3.5
   */
  public function regenerate($destroy = false, $lifetime = null)
  {
    if (null !== $lifetime)
    {
      ini_set('session.cookie_lifetime', $lifetime);
    }
    $return = session_regenerate_id($destroy);
    // Workaround for https://bugs.php.net/bug.php?id=61470 as suggested by David Grudl
    session_write_close();
    $this->closed = true;
    if (isset($_SESSION))
    {
      $backup = $_SESSION;
      $this->doSessionStart();
      $_SESSION = $backup;
    }
    else
    {
      $this->doSessionStart();
    }
    return $return;
  }
  /**
   * Force the session to be saved and closed.
   *
   * This method must invoke session_write_close() unless this interface is used for a storage object design for unit or functional testing where
   * a real PHP session would interfere with testing, in which case it should actually persist the session data if required.
   *
   * @return  void
   *
   * @see     session_write_close()
   * @since   3.5
   */
  public function save()
  {
    // Verify if the session is active
    if ((version_compare(PHP_VERSION, '5.4', 'ge') && PHP_SESSION_ACTIVE === session_status())
      || (version_compare(PHP_VERSION, '5.4', 'lt') && $this->started && isset($_SESSION) && $this->getId()))
    {
      $session = JFactory::getSession();
      $data    = $session->getData();
      // Before storing it, let's serialize and encode the JRegistry object
      $_SESSION['joomla'] = base64_encode(serialize($data));
      session_write_close();
      $this->closed  = true;
      $this->started = false;
    }
  }
  /**
   * Clear all session data in memory.
   *
   * @return  void
   *
   * @since   3.5
   */
  public function clear()
  {
    // Need to destroy any existing sessions started with session.auto_start
    if ($this->getId())
    {
      session_unset();
      session_destroy();
    }
    $this->closed  = true;
    $this->started = false;
  }
  /**
   * Performs the session start mechanism
   *
   * @return  void
   *
   * @since   3.5.1
   * @throws  RuntimeException If something goes wrong starting the session.
   */
  private function doSessionStart()
  {
    // Register our function as shutdown method, so we can manipulate it
    register_shutdown_function(array($this, 'save'));
    // Disable the cache limiter
    session_cache_limiter('none');
    /*
     * Extended checks to determine if the session has already been started
     */
    // If running PHP 5.4, try to use the native API
    if (version_compare(PHP_VERSION, '5.4', 'ge') && PHP_SESSION_ACTIVE === session_status())
    {
      throw new RuntimeException('Failed to start the session: already started by PHP.');
    }
    // Fallback check for PHP 5.3
    if (version_compare(PHP_VERSION, '5.4', 'lt') && !$this->closed && isset($_SESSION) && $this->getId())
    {
      throw new RuntimeException('Failed to start the session: already started by PHP ($_SESSION is set).');
    }
    // If we are using cookies (default true) and headers have already been started (early output),
    if (ini_get('session.use_cookies') && headers_sent($file, $line))
    {
      throw new RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line));
    }
    // Ok to try and start the session
    if (!session_start())
    {
      throw new RuntimeException('Failed to start the session');
    }
    // Mark ourselves as started
    $this->started = true;
  }
}