thehenrys.net

April 29, 2009

.NET consume a php nusoap web service server *or* PHP NuSOAP Document/Literal Web Service Server

Filed under: Programming — dh @ 11:16 am

Ripped blatently from here so that I might not ever lose this information again!

PHP NuSOAP Document/Literal Web Service Server

If you are using regular Pear SOAP, it doesn’t work in document/literal. I tried. So I turned to NuSOAP, which unfortunately has very little in the way of documented examples, especially in document/literal. I am including the server that worked for me (discovered largely through trial and error), as well as a test client. This is designed to mirror Pear SOAP as much as possible (since I was converting from one to the other). Note: document/literal in NuSOAP does not verify data types, so int, string, boolean, etc. are all converted to strings between the client and server.

Server:

require_once("nusoap/nusoap.php");

$server = new soap_server;
$server->configureWSDL('servicename', 'urn:servicename','','document');

myRegister($server,'DoSomething',
array('in' => array('Name' => 'xsd:string',
'Age' => 'xsd:int'),
'out' => array('Pass' => 'xsd:boolean')
));

//if in safe mode, raw post data not set:
if (!isset($HTTP_RAW_POST_DATA)) $HTTP_RAW_POST_DATA = implode("\r\n", file('php://input'));
$server->service($HTTP_RAW_POST_DATA);

function myRegister(&$server,$methodname,$params)
{
$server->register($methodname,$params["in"],$params["out"],
'urn:servicename', // namespace
$server->wsdl->endpoint.'#'.$methodname, // soapaction
'document', // style
'literal', // use
'N/A' // documentation
);
}

function DoSomething($Name,$Age)
{
$result=false;
if ($Name=="mleiv" && $Age==35) $result=true;
return array('Pass'=>$result);
}

Client:

require_once("nusoap/nusoap.php");

$ns="urn:servicename";
$client = new soapclient('http://localhost/wherever/SOAPServer.php?wsdl','wsdl');
if ($client->getError())
{
print "<h2>Soap Constructor Error:</h2><pre>".
$client->getError()."</pre>";
}
$params=array("Name"=>"mleiv","Age"=>35);
$result = $client->call("DoSomething",array("parameters"=>$params),$ns);
if ($client->fault) //soap_fault
{
print "<h2>Soap Fault:</h2><pre>(".$client->fault->faultcode.") ".
$client->fault->faultstring."</pre>";
}
elseif ($client->getError())
{
print "<h2>Soap Error:</h2><pre>".$client->getError()."</pre>";
}
else
{
print "<h2>Result:</h2><pre>".$result["Pass"]."</pre>";
}
print '<h2>Details:</h2><hr />'.
'<h3>Request</h3><pre>' .
htmlspecialchars($client->request, ENT_QUOTES) . '</pre>'.
'<h3>Response</h3><pre>' .
htmlspecialchars($client->response, ENT_QUOTES) . '</pre>'.
'<h3>Debug</h3><pre>' .
htmlspecialchars($client->debug_str, ENT_QUOTES) . '</pre>';

March 17, 2009

What the heck is 1.8189894035459E ?

Filed under: Programming — dh @ 3:53 pm

I have been pulling what little hair I have out for the past hour trying to figure out a very peculiar thing that was happening to me in php. I was doing some math and a function that I know was supposed to return 0 was returning 1.8189894035459E . If you called the function outside of a loop it worked fine, but is you called it in a while loop for instance, it would return this crazy value. All I had to do was to typecast the result of the integer addition to an (int) and the problem went away. Hope this might help someone in the future save some hair.

May 22, 2008

Dump one MySQL database to another MySQL database

Filed under: Programming,Server Admin — dh @ 1:28 am

mysqldump -u[uname] -p[password] [table] | mysql -u[uname] -p[password] –host=[ip address] -C [table]

I.E.: mysqldump -umy_user_name -pmy_secret_password foo_table | mysql -umy_2nd_user_name -pmy_2nd_secret_password –host=1.1.1.1 -C foo_table

(whole command should be on one line of course.) :)

May 19, 2008

PHP, OpenSSL and ftp_ssl_connect() on Win32, my journey…

Filed under: Programming,Server Admin — dh @ 1:46 pm

I need to compile php for Windows so that the ftp_ssl_connect function would be available. This is how I did it. All of this is as of today, May 19, 2008. Windows XP Pro SP2.

  • Download & Install (this is a large install > 1GB):
    » Microsoft Visual C++ 2008 Express Edition
    » Windows SDK for Windows Server 2008 and .NET Framework 3.5
  • Copy C:\Program Files\Microsoft SDKs\Windows\v6.1\Include\WinResrc.h to C:\Program Files\Microsoft SDKs\Windows\v6.1\Include\winres.h
  • Create the directory C:\work
  • Download:
    » php 5.2.6 Source Code and extract it to the C:\work\ folder.
  • Download:
    » Needed Libraries (zip.zip). Edin Kadribašic has a nice zip file with everything in it. You need to go into subfolder /php/win32 and click on zip.zip. (If this link is down try this one: http://perisama.net/ ). Create folder C:\work\php_build\ and extract the zip file into it.
  • Download:
    » Newer libxml2. The libxml package that is included in the zip file was a little out of date. Download this one and extract the contents of the zip file on top of C:\work\php_build\ . Overwrite files as needed.
  • Download & Install:
    » Win32 OpenSSL (Win32 OpenSSL v0.9.8g)
  • Patch php source:
    As of php 5.2.6, you will need to patch C:\work\php-5.2.6\ext\ftp\ftp.c in your php source directory. deciacco did some awesome work in producing a working patch. You can see his site here. You can download my patched version for php 5.2.6 here. Just replace the copy of ftp.c in your C:\work\php-5.2.6\ext\ftp\ folder.
  • Open:
    Start > Program Files > Visual C++ 9.0 Express Edition > Visual Studio Tools > Visual Studio 2008 Command Prompt
  • Type these commands into the Visual Studio 2008 Command Prompt:
    Link To Commands
    You will see many, many compile warnings. This is quite normal. :)
  • If everything went well, you should now have php.exe in the folder C:\work\Release_TS\ which has ftp_ssl_connect functionality.

    July 12, 2007

    PHPMailer

    Filed under: Programming — dh @ 2:51 pm

    Found a really cool php class today.

    PHPMailer
    http://phpmailer.sourceforge.net/

    Features

    • Can send emails with multiple TOs, CCs, BCCs and REPLY-TOs
    • Redundant SMTP servers
    • Multipart/alternative emails for mail clients that do not read HTML email
    • Support for 8bit, base64, binary, and quoted-printable encoding
    • Uses the same methods as the very popular AspEmail active server (COM) component
    • SMTP authentication
    • Word wrap
    • Address reset functions
    • HTML email
    • Tested on multiple SMTP servers: Sendmail, qmail, Postfix, Imail, Exchange, etc
    • Works on any platform
    • Flexible debugging
    • Custom mail headers
    • Multiple fs, string, and binary attachments (those from database, string, etc)
    • Embedded image support

    May 14, 2007

    mySQL left join on more than one table? yes!

    Filed under: Programming — dh @ 11:04 am

    I never knew you could do this till the other day… Man that makes it easy!

    SELECT products.product_ID, manufacturer.manufacturer_name, category.category_name
    FROM products
    left join manufacturer ON products.manufacturer_ID = manufacturer.manufacturer_ID
    left join category ON products.category_ID = category.category_ID
    ORDER BY products.product_ID

    November 9, 2006

    CSS Clipped / Rounded Corners Solution

    Filed under: Programming — dh @ 4:01 pm

    Here is a solution for clipped & rounded corners using CSS:

    Clipped & Rounded Corners

    May 24, 2006

    PHP Back Button in I.E.

    Filed under: Programming — dh @ 1:35 pm

    Man this was giving me a problem for awhile. After using session_start( ); on my pages, the back button was suddenly giving me the “Warning: Page has Expired The page you requested was created using information you submitted in a form…” crap. I added header(“Cache-control: private”); directly after the session_start( ); and now everything works great!!

    April 20, 2006

    IE Bug: One Text Input / Enter Key Doesn’t Submit

    Filed under: Programming — dh @ 10:34 pm

    Here is the fix to this quirky and aggravating bug. If you only have one input text box and you want to submit the form by pressing the enter key, IE will simply refresh the current page for you! Simply add this hidden text input between your form tags and the form will submit as expected!

    <input type="text" style="visibility:hidden;display:none;" name="dummy"></input>

    April 18, 2006

    Flash Banner with XML input.

    Filed under: Programming — dh @ 5:38 pm

    I have been creating a new site for Demott Auction and thought it would be cool to have a Flash banner that would read in a XML file that contained the upcoming auctions to display to the visitors. I have done some Flash development in the past ( version 5 ), but have never used the new flash before ( version 8 ). Below is my attempt to do just such a banner with Flash 8 (will probably work with other versions too). Hope this helps you out cause it took me a minute or two to code it up!� ;)

    OK so I’m gonna assume that you know a little about Flash ( frames, motion tweens, etc. ) and jump right into the meat of the issue. We need to read in an XML file that contains some upcoming auction data, formatted like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <Auctions>
      <Auction id="1">
    	<Date>April 30, 2006</Date>
    	<Time>9:30 AM</Time>
    	<City>Iron City</City>
    	<State>Georgia</State>
    	<Address>555 South Main Street</Address>
        <Name>12th Annual Spring Auction</Name>
        <Info>More Information Coming Soon!</Info>
      </Auction>
      <Auction id="2">
    	<Date>April 30, 2007</Date>
    	<Time>9:30 AM</Time>
    	<City>Iron City</City>
    	<State>Georgia</State>
    	<Address>555 South Main Street</Address>
        <Name>13th Annual Spring Auction</Name>
        <Info>More Information Coming Soon!</Info>
      </Auction>
      <Auction id="3">
    	<Date>April 30, 2008</Date>
    	<Time>9:30 AM</Time>
    	<City>Iron City</City>
    	<State>Georgia</State>
    	<Address>555 South Main Street</Address>
        <Name></Name>
        <Info>More Information Coming Soon!</Info>
      </Auction>
      <Auction id="4">
    	<Date>April 30, 2009</Date>
    	<Time>9:30 AM</Time>
    	<City>Iron City</City>
    	<State>Georgia</State>
    	<Address>555 South Main Street</Address>
        <Name></Name>
        <Info>More Information Coming Soon!</Info>
      </Auction>
    </Auctions>

    We need to read in this XML file and dynamically display all the upcoming auctions in the banner. I created a new movie ( 468px X 59px ) and made 4 layers: ‘flashing’, ‘auction’, ‘bg_frame’, and ‘script’. The layer ‘flashing’ handles the flashing intro text. The layer ‘auction’ is where the dynamic text box is located. The layer ‘bg_frame’ contains the black outline and white background of the banner. The ‘script’ layer is where all of the scripting takes place. We will concentrate on this layer and go into it’s details. All the code for this project is included at the end of the post. Go ahead and download it now and pull up the file banner.fla now with Flash 8 so you can follow along.

    The first frame of the ‘script’ layer is where we read in the XML file and store the auctions in an object to be used later. The script reads in a XML file and stores each auction in the global variable ‘_global.auctions’. Another global variable ‘_global.num_auctions’ keeps track of the total number of auctions in the file. We are basically building up the ‘_global.auctions’ object to contain all of the auctions that we will display later.

    var debug = 0;
    if(debug) trace(_global.auctions);
    // load XML file on first pass
    if(_global.auctions == undefined)
    {
      _global.num_auctions = 0;
      _global.auctions = new Object();
      auctions_xml = new XML();
      auctions_xml.ignoreWhite = true;
      auctions_xml.onLoad = function(success) {
              if (success) {
                      process_auctions(auctions_xml);
              }
      };
      // Load up the XML file into Flash
      auctions_xml.load('http://www.thehenrys.net/wp/wp-content/uploads/2006/04/auctions.xml');
    }
    
    // This is the function that will be called when
    // our XML document is loaded succesfully
    function process_auctions(xmlDoc_xml)
    {
      // xmlDoc_xml is now a reference to the XML
      // object where our information is stored
      auct_txt = '';
      for (var m = 0; m < xmlDoc_xml.firstChild.childNodes.length; m++)
      {
        _global.num_auctions ++;
        if(debug) trace( m+'=m '+_global.num_auctions+'=_global.num_auctions' );
        auction = new Object();
        for (var n = 0; n < xmlDoc_xml.firstChild.firstChild.childNodes.length; n++)
        {
          if(debug) trace( m+'=m '+n+'=n' );
    	  if(debug) trace(xmlDoc_xml.firstChild.childNodes[m].childNodes[n].nodeName+'='+xmlDoc_xml.firstChild.childNodes[m].childNodes[n].firstChild.nodeValue);
    	  auction[xmlDoc_xml.firstChild.childNodes[m].childNodes[n].nodeName] = xmlDoc_xml.firstChild.childNodes[m].childNodes[n].firstChild.nodeValue;
        }
        // assign this auction to the global auctions
        _global.auctions[_global.num_auctions] = auction;
      }
    }

    The line auctions_xml.onLoad = function(success)… allows us to set up a callback function to occur when we have sucessfully loaded in the XML file. NOTE: The movie will continue on before knowing whether or not we have loaded the XML file successfully. If you check the contents of the ‘_global.auctions’ global in frame 5, it may or may not have data in it depending on if the callback function has finished yet. So you are warned to leave enough time for the XML file to be loaded before trying to do anything with the ‘_global.auctions’ global. What I did was wait until frame 50 before displaying the data from the ‘_global.auctions’ global. This gives me plenty of time to read in the XML and load it. I found all this out the hard way of course. :)

    var debug = 0;
    if(_global.current_auction == undefined)
      _global.current_auction = 1;
    if(debug) trace( _global.auctions[_global.current_auction].Name+' '+_global.current_auction );
    // assign to the text box
    auct_txt = '<b>'+_global.auctions[_global.current_auction].Name+'<br>'+_global.auctions[_global.current_auction].City+', '+_global.auctions[_global.current_auction].State+' -  '+_global.auctions[_global.current_auction].Date+' '+_global.auctions[_global.current_auction].Time+'<br>'+_global.auctions[_global.current_auction].Info+'</b>';
    _global.current_auction ++;
    if(_global.current_auction > _global.num_auctions)
      _global.current_auction = 1;

    Frame 50 of the ‘script’ layer is where we display the XML data we loaded into the ‘_global.auctions’ global. Take a look at the code for it now. The first couple of lines checks for a new global variable called ‘_global.current_auction’. This is an integer representing the number of the auction that we need to display now. It is not set on the first pass, so we set it to 1. We use ‘_global.current_auction’ as the array index for the ‘_global.auctions’ object. You will see that we assign the text line to the variable ‘auct_txt’ which is what we named our text box in the ‘auction’ layer. After assignment of the text, we increment the ‘_global.current_auction’ and decide if we need to start over back at 1. That’s all there is to it!

    Finished Banner:

    banner.swf
    banner.fla
    auctions.xml