适用于PHP的SSRS SDK:不适用于PHP 5.5

适用于PHP的SSRS SDK:不适用于PHP 5.5

问题描述:

I'm using the SSRS SDK For PHP which has not been updated since years surprisingly (08.04.2010) . It works fine under PHP 5.4 (5.4.44) but not under 5.5+ (5.5.37, 5.6.28, 7.x)

The error is :

array ( )Failed to connect to Reporting Service Make sure that the url (https://myHost:60004/ReportServer/) and credentials are correct!

The exception is thrown in line 207 because the var $content is equals to FALSE (so can't load the content).

It's perfectly fine with PHP 5.4.44.

I can't find the "SSRS SDK For PHP" documentation regarding the PHP version supported...

I'm not using any framework such as Symfony2, CakePHP, Zend Framework,... except Bootstrap.

Does anyone know or have figured out this issue?

EDIT

As asked in a comment, here is my code :

function buildSSRSReport($companyId)
    {
        require_once '../tools/SSRSReport/SSRSReport.php';

        try {
            // Create a connection to the SSRS Server
            $rs = new SSRSReport(new Credentials(SSRS_USER_ID, SSRS_PASSWORD), SSRS_REPORT_SERVER_URL);
            $sqlConnection = self::getSqlConnection();

            // Load the report and specify the params required for its execution
            $executionInfo = $rs->LoadReport2(self::getSSRSEnvironment(), NULL);
            $parameters = array();
            $parameters[0] = new ParameterValue();
            $parameters[0]->Name = "CompanyId";
            $parameters[0]->Value = $companyId;
            $rs->SetExecutionParameters2($parameters);

            // Require the Report to be rendered in HTML format
            $renderAsHTML = new RenderAsPDF();

            // Set the links in the reports to point to the php app
            //$renderAsHTML->ReplacementRoot = getPageURL();

            // Set the root path on the server for any image included in the report
            //$renderAsHTML->StreamRoot = './images/';

            // Execute the Report
            $result_html = $rs->Render2($renderAsHTML,
                PageCountModeEnum::$Actual,
                $Extension,
                $MimeType,
                $Encoding,
                $Warnings,
                $StreamIds);

            $pdfFileName = self::getCompanyAlias($sqlConnection, $companyId) . ".pdf";

            header('Content-Type: application/x-download');
            header('Content-Disposition: attachment; filename="' . $pdfFileName . '"');
            header('Cache-Control: private, max-age=0, must-revalidate');
            header('Pragma: public');

            return $result_html;
        } catch (SSRSReportException $serviceException) {
            echo $serviceException->GetErrorMessage();
        }

    }

    function getSSRSEnvironment()
    {
        return "/DEV/CompanyESGReportingServices-DEV/Main";
    }

    private function getSqlConnection()
    {
        require_once("../inc/eth_connexion.php");
        /* These 4 variables are contained within the eth_connexion.php file */
        $serverName = SQL_SERVERNAME;
        $userName = SQL_USERNAME;
        $dbName = SQL_DATABASENAME;
        $password = SQL_PASSWORD;

        // SQLSRV : Connection array used when calling SQL via sqlsrv_query
        $connectionInfo = array("Database"=> SQL_DATABASENAME,
            "UID"=> SQL_USERNAME,
            "PWD"=> SQL_PASSWORD,
            "ReturnDatesAsStrings" => true);

        $sqlConnection = sqlsrv_connect($serverName, $connectionInfo);
        if (!$sqlConnection) {
            die('Can't log to the database');
        }

        return $sqlConnection;
    }

And here is the source code of the SSRSReport constructor (original from the SSRS SDK For PHP) :

public function SSRSReport($credentials, $url, $proxy = null)
{        
    $this->_BaseUrl = ($url[strlen($url) - 1] == '/')? $url : $url . '/';
    $executionServiceUrl = $this->_BaseUrl . self::ExecutionService;
    $managementServiceUrl = $this->_BaseUrl . self::ManagementService;

    $options = $credentials->getCredentails();
    $stream_conext_params = array( 'http' =>
                                     array('header' =>
                                      array($credentials->getBase64Auth())));
    if(isset($proxy))
    {
        $options = array_merge($options, $proxy->getProxy());
        $stream_conext_params['http']['proxy'] = 'tcp://' .
                                                    $proxy->getHost() .
                                                    ':' .
                                                    $proxy->getPort();
        if($proxy->getLogin() != null)
        {               
            $stream_conext_params['http']['header'][1] = $proxy->getBase64Auth();
        }            
    }

    /**
     * If the SoapClient call fails, we cannot catch exception or supress warning
     * since it throws php fatal exception.
     * http://bugs.php.net/bug.php?id=34657
     * So try to load the wsdl by
     * calling file_get_contents (with warning supressed i.e. using @ symbol
     * infront of the function call)
     * http://*.com/questions/272361/how-can-i-handle-the-warning-of-filegetcontents-function-in-php
     */
    $context = stream_context_create($stream_conext_params);
    $content = @file_get_contents($executionServiceUrl, false, $context);
    if ($content === FALSE) // I'M GOING HERE WITH PHP 5.5+ 
    {
        throw new SSRSReportException("",
                    "Failed to connect to Reporting Service  <br/> Make sure " .
                    "that the url ($this->_BaseUrl) and credentials are correct!");
    }

    $this->_soapHandle_Exe =  new SoapClient ($executionServiceUrl, $options);
    $this->_soapHandle_Mgt =  new SoapClient ($managementServiceUrl, $options);
    $this->ClearRequest();
}

The exact error message is :

https://myPublicHostProvider:60004/ReportServer/ReportExecution2005.asmx?wsdl Authorization: Basic = array(1) { ["http"]=> array(1) { ["header"]=> array(1) { [0]=> string(57) "Authorization: Basic =" } } } Failed to connect to Reporting Service Make sure that the url (https://myPublicHostProvider:60004/ReportServer/) and credentials are correct!

Thanks for your help MiSAKACHi. It pointed me on the right direction. Actually, I'm using a remote dedicated server on a hosting provider on which I don't have access. But the <RSWindowsBasic/> is there as it can load the report with PHP 5.4. Everything is fine under this version.

Thanks to you, I found the issue : I'm using HTTPS and with HTTPS it doesn't work whereas it works when I'm using HTTP ! I'm check with my hosting provider if they can do something.

EDIT - Solution

My hosting provider fixed the issue last year (forgot to post it here). During the time it wasn't fixed, I was still under PHP 5.4. I paste their original message :

These issues that you describe is because the installed Certificate is a self signed Certificate. New Web Browsers and PHP Version don't accept these Certificates because of Security Risks.

We have changed the Certificate with a official issued Certificate

SSRS SDK for PHP Configuration Pointers

  • Make sure your Report Server instance is accessible. Test it by going to the Web Portal or the Service URL.

  • Provide your credentials. If you are authenticated, then the credentials that you used are valid.

  • After that, go to the directory \Program Files\Microsoft SQL Server\<INSTANCE_NAME>\Reporting Services\ReportServer and look for the file named rsreportserver.config

  • Find this snippet

    <Authentication>
    <AuthenticationTypes>
        <RSWindowsNTLM/>
    </AuthenticationTypes>
    <Authentication>
    
  • Add <RSWindowsBasic/> below the <RSWindowsNTLM/> entry.

For your reference, this was the snippet I used to test my instance during configuration.

require_once( 'SSRSReport\bin\SSRSReport.php' );

define( 'UID', 'DOMAIN\Username' );
define( 'PASWD', 'Password' );
define( 'SERVICE_URL', 'http://127.0.0.1/SERVICE_URL/' );

try {
    $ssrs_report = new SSRSReport( new Credentials( UID, PASWD ), SERVICE_URL );
    $ssrs_report->LoadReport2( '/test', NULL );
    $renderAsHTML = new RenderAsHTML();
    $result_html = $ssrs_report->Render2(
        $renderAsHTML,
        PageCountModeEnum::$Estimate,
        $Extension,
        $MimeType,
        $Encoding,
        $Warnings,
        $StreamIds
    );
    echo $result_html;  
} catch ( SSRSReportException $serviceException ) {
    echo $serviceException->GetErrorMessage();
}

It can successfully load the RDL that is located on the load path.

I just want to add that I was facing issue using the codeplex ssrsphp, therefore I googled and found another sdk, which works perfectly. I'm using php 7+. Here is the link and I'm available if there're any questions related to this.