【问题标题】:How do I create a Magento session outside of Magento?如何在 Magento 之外创建 Magento 会话?
【发布时间】:2012-01-28 20:07:15
【问题描述】:

我可以使用下面流行的方法完美地访问 Magento 之外的现有会话。

require 'app/Mage.php';
$mageRunCode = isset ( $_SERVER ['MAGE_RUN_CODE'] ) ? $_SERVER ['MAGE_RUN_CODE'] : '';
$mageRunType = isset ( $_SERVER ['MAGE_RUN_TYPE'] ) ? $_SERVER ['MAGE_RUN_TYPE'] : 'store';
$app = Mage::app ( $mageRunCode, $mageRunType );
Mage::getSingleton ( 'core/session', array ('name' => 'frontend' ) );

这很好用,但是我如何在 Magento 之外实际创建一个 Magento 会话,以填充 log_url、log_visitor 等表以及将访问者数据分配给会话?

目前,用户直接从另一个网站到达我网站上的页面。此特定页面在 Magento 之外,但我需要使用以下代码访问他们的访客 ID:

Mage::getSingleton ( 'log/visitor' )->getId()

如果用户以前去过我的 Magento 商店,这很好用,但如果没有,它只会返回一个布尔值 false。我想做的是检查是否为访问者 ID 设置了值,如果没有,则在 Magento 之外的第一页上创建访问者,以便我可以在此页面上使用访问者 ID。同样重要的是,一旦用户进入我的 Magento 商店,相同的访客 ID 将应用于他们对我的目录的导航,即相同的会话。有什么想法吗?

【问题讨论】:

    标签: session magento logging visitor-pattern


    【解决方案1】:

    嗯,我想通了。虽然我必须承认这不是最干净的解决方案,但它完全符合我的预期。对于其他想要这样做的人,我已将我的代码摘录粘贴在下面:

    require 'app/Mage.php';
    $mageRunCode = isset ( $_SERVER ['MAGE_RUN_CODE'] ) ? $_SERVER ['MAGE_RUN_CODE'] : '';
    $mageRunType = isset ( $_SERVER ['MAGE_RUN_TYPE'] ) ? $_SERVER ['MAGE_RUN_TYPE'] : 'store';
    $app = Mage::app ( $mageRunCode, $mageRunType );
    $core_session = Mage::getSingleton ( 'core/session', array ('name' => 'frontend' ) );
    $write = Mage::getSingleton ( 'core/resource' )->getConnection ( 'core_write' );
    
    $url = Mage::getUrl ( '*/*/*', array ('_current' => true ) );
    
    Mage::getSingleton ( 'core/session' )->setLastUrl ( $url );
    
    $visitor_id = $_SESSION ['core'] ['visitor_data'] ['visitor_id'];
    
    if (! empty ( $visitor_id )) {
        Mage::getSingleton ( 'log/visitor' )->setId ( $visitor_id );
    } else {
        Mage::getSingleton ( 'customer/session' )->setWishlistItemCount ( 0 );
        Mage::getSingleton ( 'catalog/session' )->setCatalogCompareItemsCount ( 0 );
    
        $write->query ( "INSERT INTO log_url_info (url, referer) VALUES (?, ?)", array ($url, Mage::helper ( 'core/http' )->getHttpReferer ( true ) ) );
        $url_id = $write->lastInsertId ();
        $log_visitor = Mage::getSingleton ( 'log/visitor' )->initServerData ()->setFirstVisitAt ( now () )->setIsNewVisitor ( true )->setLastVisitAt ( now () )->setLastUrlId ( $url_id )->save ();
        $write->query ( "INSERT INTO log_url (url_id, visitor_id, visit_time) VALUES (?, ?, ?)", array ($url_id, $log_visitor->getId (), now () ) );
        $core_session->setVisitorData ( $log_visitor->getData () );
    
        $visitor_id = $log_visitor->getId ();
    }
    

    我希望这对其他人有所帮助,这样他们就不会像我那样扯掉头发。

    【讨论】:

    • 这对我有帮助,谢谢。让不同领域的会话发挥作用的关键是在使用其他会话之前使用$core_session = Mage::getSingleton ( 'core/session', array ('name' => 'frontend' ) 行。
    【解决方案2】:

    不确定这是否有帮助,但这里有一些代码可以帮助通过 app() 引导方法更准确地加载 magento。通过调度一些事件,它实例化访问者对象并加载一些其他有用的对象/资源,使其功能类似于原生 Magento 的 run():

    <?php
    require_once $_SERVER['DOCUMENT_ROOT'].'/app/Mage.php';
    umask(0);
    //Scope
    $scope = 'frontend';
    // Initialize Mage_Core_Model_App object
    $app = Mage::app('', 'store');
    // Grab the front controller
    $frontController = $app->getFrontController();
    // Load configuration
    Mage::getConfig()->init();
    // Load event observers for specified scope
    Mage::getConfig()->loadEventObservers($scope);
    // Set the theme (not sure if needed, appears it falls back to whats set in the admin)
    //Mage::getdesign()->setTheme('morris-v2');
    // Add event area for event dispatching
    $app->addEventArea($scope);
    //Init the session by calling singleton
    Mage::getSingleton('core/session', array('name'=>$scope));
    //dispatch  layout load before event, this is useful for observing in case of ab testing etc
    Mage::dispatchEvent('controller_action_layout_load_before', array('action'=>$frontController, 'layout'=>Mage::getSingleton('core/layout')));
    //dispatch action predispatch, this has some observers which instantiate needed variables such as log/visitor
    Mage::dispatchEvent('controller_action_predispatch', array('controller_action'=>$frontController));
    

    【讨论】:

      【解决方案3】:

      实际上这些答案不起作用,因为我在 Magento 的子目录中运行代码。 Magento 查看您的 SCRIPT_NAME 变量的目录名,并将其设置在那里。因此,如果您从 /foo/test.php 设置会话,那么 cookie 将仅对 /foo/ 有效,如果 magento 位于“/”,它将看不到 cookie。

      在这种情况下,如果您的脚本是最初创建 cookie 的脚本,您必须强制 cookie 对“/”有效。

      症状是您的更改没有生效,您可以在“/var/session”中看到两个会话。这似乎是不可预测的,但不同的是如果 Magento 先创建会话,它对所有路径都有效。如果您的脚本首先创建它,它对 Magento 无效,浏览器会忽略它,并且 Magento 会创建一个新会话。

      示例工作代码:

      <?php
      ini_set('display_errors', 1);
      require_once $_SERVER['DOCUMENT_ROOT'] . '/app/Mage.php';
      
      Mage::app('mystore', 'website');
      
      $session = Mage::getSingleton('core/session', array('name' => 'frontend'));
      $sessionName = $session->getSessionName();
      $sessionId = $session->getSessionId();
      
      /**
       * Magento sets the cookie valid for the path "/recommend", but we need it available always (path "/")
       */
      setcookie($sessionName, $sessionId, null, '/');
      

      (我使用 DOCUMENT_ROOT 的原因是因为我正在使用来自该模块的 modman 映射,它通过符号链接运行代码)。重要的部分是 setcookie()。通过检查 http 标头,您会看到设置了两个 cookie。一个用于“/foo”,一个用于“/”。如果不调用 setCookie,只会创建第一个会话,当通过“/index.php”而不是“/foo/test.php”访问时,Magento 看不到该会话

      【讨论】:

      • 正是我需要的!我想通了,但没有注意到 cookie 范围!队友的欢呼声! :)
      【解决方案4】:
      Mage::getSingleton('core/session', array ('name' => 'frontend' ))->setCaptchaValue($digit); 
      

      还有

      Mage::getSingleton('core/session', array ('name' => 'frontend' ))->getCaptchaValue();
      

      在 Magento 之外为 Magento 会话工作

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-16
        • 2012-06-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多