From:             [EMAIL PROTECTED]
Operating system: Red Hat Linux 7.1
PHP version:      4.3.0RC3
PHP Bug Type:     Output Control
Bug description:  Out Put Error from United Parcel Service Rate/Service CGI File

I have create a php script that generates a shipping cost from a United
Parcel Service host. The script has worked fine on all on all PHP releases
prior to version 4.3.0RC2.


Example Script:
##########################START###########################
<?
/*
This is a UPS Shipping Program created with PHP (http://www.php.net). This
program is design to be flexiable have the ability to perform several task
including:
(1) Generate live shippping rates from a UPS server.
(2) Add the retail item cost per distributor if the retailer uses multiple
distributors.
(3) Add the whole sale cost per item while categorizing the whole sales
cost per distributor.
(4) Add the item weight per item while catagorizing the item weight per
distributor.
(5) Add any applicable distributor handling fees to the final shipping
cost.
(6) Seperate the UPS shipping fee(s), distributor handling fee(s), per
item whole sale cost and per item retal cost of CHECK OUT ITEMS and
Pre-Order items.

REQUIRMENTS:
(1) MYSQL 3.x or later.
(2) PHP 4.x (version 4.3.0RC2 is not compatable)or later compilled with
MYSQL and BCMATH. 
(3) A Web Server.

Special Note(s): 
(1) The Check Out Items and Pre-Orders Items scripts are on seperate files
to reduce the number of lines of code.
(2) The PHP code uses objects. There fore a MYSQL Table will be needed
with columns named as shown in the code bellow.
(3) The mysql_fetch_object names ($string->string) names can be changed
but changing any other codeing will cause this program to error out.
(4) To simplify the file to file linking the following (INCLUDE/REQUIRE
functions) codes are located on a seperate file.

//Set the bcmath scale to two digits aftr the decimal point.
bcscale(2);

//Decode shoping cart, check out subtotal and pre-order sub totlal strings
for later use.
$decode_basket = base64_decode($basket);

//Explode the shop cart string into an array for use in the shipping
calculators bellow.
$percent_sym = explode("%","$decode_basket");

//Shipping calculator.
if($check_out_sub_total != ""){
        include "../check_out_items_shipping.php";
        $decode_check_out_sub_total = base64_decode($check_out_sub_total);
}
if($pre_order_sub_total != ""){
        include "../pre_order_items_shipping.php";
        $decode_pre_order_sub_total = base64_decode($pre_order_sub_total);
}
*/

        //Arrays for use in the $post_codes array_push function.
        $check_out_postal_codes = array();
        $check_out_dist_handle_fee_array = array();
        
        //A loop to seperate the basket string and extract the DB table name,
item number and purchase quantity
        foreach($check_out_percent_syms as $items){
                //Seperate the basket string into speices to determine which table to
target and perform various DB selects. 
                $carot = explode("^", "$items");
                $asterk = explode("*", "$carot[1]");
                $get_shipping_info = mysql_query("select * from $carot[0] where 
item_num
= '$asterk[0]'");
                $shipper_info = mysql_fetch_object($get_shipping_info);
                
                //An if statment to isolate the check out items from the pre-order
items.  
                if($shipper_info->availability !== "pre-order"){
                        
                        //Push the postal codes into an array.
                        array_push($check_out_postal_codes,
$shipper_info->shipper_postal_code);
                        
                        //Multiply the retail and whole sale items by their perspective
quantities.     
                        $check_out_retail_cost[$shipper_info->distributor] +=
"$shipper_info->retail_price" * "$asterk[1]";
                        $check_out_wholesale_cost[$shipper_info->distributor] +=
"$shipper_info->wholesale_price" * "$asterk[1]";
                        $check_out_distributor_weight[$shipper_info->distributor] +=
"$shipper_info->box_weight" * "$asterk[1]";
                                                
                        /*If there are duplicate postal codes and handling fees the 
items are
probalby from the same distributor and duplicate shipping fees should not
be applicable.  
                        The folowing PHP functions array_unique removes duplicate 
postal
codes.*/
                        $check_out_duplicate_postal_codes =
array_values(array_unique($check_out_postal_codes));
                        
                        //Strings for the shipping calculator.  
                        $first_codes = "POST /using/services/rave/qcost_dss.cgi 
HTTP/1.0\n";
                        $first_codes .= "Content-type: 
application/x-www-form-urlencoded\n";
                        //Notice that the content length is inside of a loop bellow.
                        $second_codes = "AppVersion=1.2&";
                        $second_codes .= "AcceptUPSLicenseAgreement=YES&";
                        $second_codes .= "ResponseType=application/x-ups-rss&";
                        $second_codes .= "ActionCode=3&";
                        $second_codes .= "ServiceLevelCode=$ship_method&";
                        $second_codes .= "RateChart=Regular+Daily+Pickup&";
                        //Notice that the shipper postal code is inside of a loop 
bellow.
                        $third_codes = "ConsigneePostalCode=$ship_postal_code&";
                        $third_codes .= "ConsigneeCountry=$ship_country&";
                        //Notice that the weight is inside of a loop bellow.
                
                        //In a previous page I have a company text field to determine 
if the
shipping destination is residential or commercial.
                        if($ship_company != "") {
                                $fourth_codes = "ResidentialInd=0&";
                        }               
                        else{$fourth_codes .= "ResidentialInd=1&";}
        
                        $fourth_codes .= "PackagingType=00\n\n";
                
                }//END FIRST FOREACH LOOP.
        }//END FIRST IF STATEMENT       
                                        
                
        //A SECOND IF STATEMENT TO DETERMINE IF GENERATING A SHIPPING RATE IS
NECESSARY.
        if(isset($check_out_duplicate_postal_codes)){
                foreach($check_out_duplicate_postal_codes as $check_out_postal_code){
                        $get_dist_info = mysql_query("select * from distributors where
dist_ship_postal_code = '$check_out_postal_code'");
                        $dist_info = mysql_fetch_object($get_dist_info);
                        mysql_free_result($get_dist_info);
                
                        //The list function is used inside of a if statement to 
determin if
multile distributors are present and to
                        //extract the weight per distribtor. The $value variable is 
the actual
weight.
                        if(count($check_out_distributor_weight) <= "1"){
                                $value = 
$check_out_distributor_weight[$dist_info->dist_code];
                        }
                        elseif(count($check_out_distributor_weight) > "1" ){           
         
                                list(,$value) = each($check_out_distributor_weight);
                        }
                        
                        //A series of ifelse statments for use with the contentlengt. 
The
starting lavue of 265 is an educated guess of a begining contentlength.
                        if(strlen($value) == "1"){
                                $length = "265"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "2"){
                                $length = "266"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "3"){
                                $length = "267"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "4"){
                                $length = "268"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "5"){
                                $length = "269"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "6"){
                                $length = "270"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "7"){
                                $length = "271"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "8"){
                                $length = "272"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "9"){
                                $length = "273"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "10"){
                                $length = "274"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "11"){
                                $length = "275"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "12"){
                                $length = "276"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "13"){
                                $length = "277"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "14"){
                                $length = "278"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "15"){
                                $length = "279"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "16"){
                                $length = "280"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "17"){
                                $length = "281"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "18"){
                                $length = "82"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "19"){
                                $length = "283"+(strlen($ship_postal_code));
                        }
                        elseif(strlen($value) == "20"){
                                $length = "284"+(strlen($ship_postal_code));
                        }
                        
                        //All of the above codes are joined together. The $all_codes 
variable
will be POSTED to the www.ups.com/using/services/rave/qcost_dss.cgi file.
                        $all_codes = "$first_codes"."Content-length:
$length\n\n"."$second_codes"."ShipperPostalCode=$dist_info->dist_ship_postal_code&"."$third_codes"."PackageActualWeight=$value&"."$fourth_codes";

                        
                        //Open a socket to ups.com to get shipping rates.
                        $open_sock = fsockopen("www.ups.com",80, $errno, $errstr,30);
                        if(!($open_sock)){
                                die(header("location:
http://$none_secured_domain/shipping_error.php?ship_method=$ship_method&ups=false";));
                        } 
                        else {
                                while(!(feof($open_sock))){
                                fputs($open_sock, $all_codes);
                                while($line = fgets($open_sock, 1000)){ 
                                        $contents .= $line;
                                        $check_out_find_rate = explode("%", 
$contents);
                                        break;
                                                }                                      
 
                                        }
                                }
                                
                        //if the shipping rate can not be found the script dies and 
directs the
user to a error page.
                        if($check_out_find_rate[14] == false){
                                fclose($open_sock);
                                mysql_close($connect);
                                die(header("location:
http://$none_secured_domain/shipping_error.php?ship_method=$ship_method";));
                                }
                        
                        //Use this variable string to store the shipping cost for each 
distcode
in a $key. 
                        //Example: $check_out_dist_ups_rates[abc] will print $0.00.    
 
                        $check_out_dist_ups_rates[$dist_info->dist_code] +=
"$check_out_find_rate[14]";
                
                        //Increment the ups rate to add all of the UPS shipping 
charges.
                        $check_out_ship_rate += $check_out_find_rate[14];
                
                        //This script has problems with not over writting $contents so 
the
unset function is used to clear out the $contents variable.
                        unset($contents);
                        fclose($open_sock);
                                        
                }//END FOREACH LOOP
                        
                        //Loop through each wholesale price to determine if a handling 
fee is
applicable and to obtain the per item 
                        //wholesale cost and per distributor handling fee(s).
                        //The $value variable represents a Distributors minmum order 
dollare
amount that will be aplied unless
                        //a order oabove the minimum. Example: Techdata charges $5.00 
per
customer address unless the order excedds $500.00.
                        while(list($key, $value) = each ($check_out_wholesale_cost)){
                                $check_out_wholesale .= "$key"."_"."$value"."%";
                                $get_handling_fee_minimum = mysql_query("select * from 
distributors
where dist_code = '$key'");
                                $handling_fee = 
mysql_fetch_object($get_handling_fee_minimum);
                                mysql_free_result($get_handling_fee_minimum);
                                if("$value" < "$handling_fee->dist_shipp_minimum"){
                                        $check_out_ship_fee += 
"$handling_fee->dist_shipp_fee";
                                }
                        }
                        //Cut the last percent character off of the strings above.
                        //$check_out_dist_handle_fee_string =
substr("$check_out_dist_handle_fee", 0,
strlen($check_out_dist_handle_fee)-1);
                        $check_out_wholesale_items_cost_string = 
substr("$check_out_wholesale",
0, strlen($wholesale)-1);
                
                        //Loop through each retail price to extract the retail cost 
per item.   
                        while(list($key, $value) = each ($check_out_retail_cost)){
                                $check_out_retail .= "$key"."_"."$value"."%";
                        }
                        //Cut the last percent character off of the $check_out_retail 
above.    
                        $check_out_retail_items_cost_string = 
substr("$check_out_retail", 0,
strlen($retail)-1);
                
                //Loop throught the UPS rates to extract the UPS shipping rates per
distributor and to assemble
                //string to represent the distributor handling fees.
                while(list($key, $value) = each ($check_out_dist_ups_rates)){
                        $check_out_ups .= "$key"."_"."$value"."%";
                        $get_dist_check_out_handle_fee = mysql_query("select * from
distributors where dist_code = '$key'") or die(mysql_error());
                        $check_out_dist_handle_fee =
mysql_fetch_object($get_dist_check_out_handle_fee);
                        $check_out_dist_handle_fee_string .=
"$key"."_"."$check_out_dist_handle_fee->dist_shipp_fee"."%";
                        mysql_free_result($get_dist_check_out_handle_fee);
                }
                
                //Cut the last percent character off.
                $check_out_items_ups_dist_rates = substr("$check_out_ups", 0,
strlen($check_out_ups)-1);
        
        //Add the DISTRIBUTOR HANDLING FEE(S) and the UPS SHIPPING RATE(S) to
calculate a complete SHIPING & HANDLING CHARGE for the customer. This
charge is for CHECK OUT ITEMS only.
        $complete_check_out_items_shipping_handling_charge =
bcadd($check_out_ship_rate, $check_out_ship_fee);
}//END IF STATEMENT
?>

#########################END###########################


The way the script works is that the scipt contacts a
www.ups.com/using/services/rave/qcost_dss.cgi server which outputs text
like the one bellow:


#########################START############################
HTTP/1.1 200 OK
Server: Netscape-Enterprise/6.0
Date: Sun, 15 Dec 2002 04:21:03 GMT
Content-type: multipart/mixed;boundary=UPSBOUNDARY
Content-length: 267
Connection: close

POST /using/services/rave/qcost_dss.cgi HTTP/1.0
Content-type: application/x-www-form-urlencoded
Content-length: 270

AppVersion=1.2&AcceptUPSLicenseAgreement=YES&ResponseType=application/x-ups-rss&ActionCode=3&ServiceLevelCode=GND&RateChart=Regular+Daily+Pickup&ShipperPostalCode=55428&ConsigneePostalCode=48235&ConsigneeCountry=US&PackageActualWeight=2&ResidentialInd=0&PackagingType=00


<HTML>
<BODY>
</BODY>
</HTML>


--UPSBOUNDARY
Content-type: application/x-ups-rss
Content-length: 78

UPSOnLine%1.2%0000%0000Success%3%GND%55428%US%48235%US%004%2%3.92%0.00%3.92%-1

--UPSBOUNDARY--
###########################END##############################


The script will then join(.=) the text into an array which is exploded by
a % symbol in this case the rate is 3.92 as indicated by $var[14].

Unfortunatly PHP version 4.3.0RC2 only outputes the folowing line:

##############################START#########################
HTTP/1.1 200 OK
##############################END###########################

 

-- 
Edit bug report at http://bugs.php.net/?id=21023&edit=1
-- 
Try a CVS snapshot:         http://bugs.php.net/fix.php?id=21023&r=trysnapshot
Fixed in CVS:               http://bugs.php.net/fix.php?id=21023&r=fixedcvs
Fixed in release:           http://bugs.php.net/fix.php?id=21023&r=alreadyfixed
Need backtrace:             http://bugs.php.net/fix.php?id=21023&r=needtrace
Try newer version:          http://bugs.php.net/fix.php?id=21023&r=oldversion
Not developer issue:        http://bugs.php.net/fix.php?id=21023&r=support
Expected behavior:          http://bugs.php.net/fix.php?id=21023&r=notwrong
Not enough info:            http://bugs.php.net/fix.php?id=21023&r=notenoughinfo
Submitted twice:            http://bugs.php.net/fix.php?id=21023&r=submittedtwice
register_globals:           http://bugs.php.net/fix.php?id=21023&r=globals
PHP 3 support discontinued: http://bugs.php.net/fix.php?id=21023&r=php3
Daylight Savings:           http://bugs.php.net/fix.php?id=21023&r=dst
IIS Stability:              http://bugs.php.net/fix.php?id=21023&r=isapi

Reply via email to