A Flash Developer Resource Site

Page 1 of 2 12 LastLast
Results 1 to 20 of 24

Thread: change variable in SWF with PHP

  1. #1
    Registered User
    Join Date
    Apr 2001
    Location
    Akron OH, USA
    Posts
    4,841

    change variable in SWF with PHP

    I have written a php script that changes the value of a string within a SWF file. I use the php script on the server side to hard code new values for variables in a SWF.

    I wrap values in xml tags to identify the variables. For example, in the Flash authoring tool I create an actionscirpt variable:

    fristname = "<fn>First Name1</fn>" // has 20 characters

    The php script opens the SWF, and finds and replaces the text within the <fn> tags with my new text value.

    The problem is that the SWF file expects the character length of the variable value to be the same length as the original value (20 characters in the above example). There is a binary value that defines the length of the firstname variable. Flash will not display the swf if the value is not the exact length that the binary value defines. I can work around this when I pass values shorter than the original, by padding the string with spaces, but do not have a solution for longer values.

    // pad the new 7 character string with 5 spaces so the entire string totals 20, including the tags
    firstname = "<fn>new val_____</fn>"

    My next goal is to use php to change the binary value of the variable length so that it matches the string I want to insert, so I do not have to truncate strings that are too long and pad strings that are too short.

    So I want to be able to use php to write any new string into a given variable.

    Are there any PHP based open source solutions that do something similar? I am using a shared web server and cannot install c libraries like MING or com objects. So this would be a php solution only.

    If not, can someone help me understand how I would find and change the binary value of the variable? I can follow up with php specific questions in another forum, I am just trying to get some understanding of how a script might find the variable corresponding to a given text within a SWF file, read and write the binary value defining the length of the variable.

    Thanks for any help or suggestions.

  2. #2
    Registered User
    Join Date
    Feb 2001
    Posts
    13,041
    Hi,

    reading a swf file through php, and then altering some values, seems to be a big task - although it is feasible. There is an easier approach, if it suits your application: you could create a swf without these data, and then use php to amend the swf with just one action block that sets all the required variables.
    This is equivalent to adding something like
    Code:
    var name = 'John Doe';
    var amount = 54.00;
    var counter = 23;
    to the first frame. Of course, if you dont want to clutter the root namespace, you could also compile
    Code:
    var mydata = {name:'John Doe', amount:54.00, counter:23};
    Musicman
    Last edited by Musicman; 03-02-2008 at 09:30 AM.

  3. #3
    Registered User
    Join Date
    Apr 2001
    Location
    Akron OH, USA
    Posts
    4,841
    thanks for the reply.

    yes that approach would work fine in my case. All I need to do is take user input from a web form and insert the data into an existing SWF.

    These are Flash 4 compatible swf.

    Do you have any suggestions on how I would approach this problem with PHP?

  4. #4
    Registered User
    Join Date
    Feb 2001
    Posts
    13,041
    Hi,

    have a look at www.fontimages.org.uk

    Musicman

  5. #5
    Registered User
    Join Date
    Apr 2001
    Location
    Akron OH, USA
    Posts
    4,841
    do you have a license for these scripts?

  6. #6
    Registered User
    Join Date
    Feb 2001
    Posts
    13,041
    Hi,

    it is GPL

    Musicman

  7. #7
    Junior Member
    Join Date
    Feb 2009
    Posts
    3

    Exclamation

    Hi musicman,

    I have downloaded your script, and it works fine on test swf. However when I add to the swf a movie clip it is not working anymore...

    for example I drawed some shape , then I added a button with the following actionScript:

    Code:
    on(release){
    	getURL(clickTag, "_blank");
    }
    finally I add a value for clickTag parameter by your script, and it works fine

    then I added a movie clip to my swf, and it is no more working: the php page is returning an empty swf file.

    Can you help me please??

  8. #8
    Registered User
    Join Date
    Feb 2001
    Posts
    13,041
    Hi,

    could you show the actual swf where this happens?

    Musicman

  9. #9
    Junior Member
    Join Date
    Feb 2009
    Posts
    3

    Unhappy

    sorry:

    I don't know why today it is working... I don't know...

    I have an other problem:

    I can't download the flas file. When I embed your script in an html page, it is showing perfectly the new modified swf. but I don't know how to donload it. when I open the page of the script it is downloading an incorrect flash file (not empty, and not corrupted).

    here is an example of what I want to do: www.aslabs.com/swf/index.php
    you have here a flash called final.swf wich have at the top a button calling to clickTag parameter. from the first page I add in the link I wanto to open in the session then I have this php :

    PHP Code:
    <?php
    session_start
    ();
    class 
    object {}
    class 
    swf
    {    var $fh;
        var 
    $buffer;
        var 
    $bufbits;
        var 
    $stdout 0;

        function 
    swf($fname$mode)
        {    if(
    ereg("w"$mode) && $fname == "")
                
    $this->stdout 1;
            else
                
    $this->fp fopen($fname$mode);
            
    $this->buffer 0;
            
    $this->bufbits 0;
        }
        function 
    getc()
        {    
    $buf fread($this->fp1);
            
    $this->buffer ord($buf);
            return 
    $this->buffer;
        }
        function 
    readnbits($n)
        {    
    $ret $this->buffer;
            if(
    $n == $this->bufbits)
            {    
    $this->bufbits 0;
                
    $this->buffer 0;
                return 
    $ret;
            }
            if(
    $n $this->bufbits)
            {    
    $n -= $this->bufbits;
                while(
    $n 8)
                {    
    $ret <<= 8;
                    
    $ret += $this->getc();
                    
    $n -= 8;
                }
                
    $this->getc();
                if(
    $n 0)
                {    
    $ret <<= $n;
                    
    $this->bufbits $n;
                    
    $ret += $this->buffer >> ($n);
                    
    $this->buffer &= (<< $this->bufbits)-1;
                }
                return 
    $ret;
            }
            
    $ret $this->buffer >> ($this->bufbits $n);
            
    $this->bufbits -= $n;
            
    $this->buffer &= (<< $this->bufbits)-1;
            return 
    $ret;
        }
        function 
    bytealign()
        {    
    $this->bufbits 0;
            
    $this->buffer 0;
        }
        function 
    readnSbits($n)
        {    
    $res $this->readnbits($n);
            if(
    $res & (<< ($n-1)))
                return 
    $res - (<< $n);
            else
                return 
    $res;
        }
        function 
    readheader()
        {    
    $res = new object();
            
    $buf fread($this->fp3);
            if(
    $buf != "FWS") return null;
            
    $buf fread($this->fp1);
            
    $res->vers ord($buf);
            
    $buf fread($this->fp4);
            
    $tmp unpack("Vsize"$buf); $res->fsize $tmp["size"];
            
    $nbits $this->readnbits(5);
            
    $xl $this->readnSbits($nbits); $xr $this->readnSbits($nbits);
            
    $yl $this->readnSbits($nbits); $yr $this->readnSbits($nbits);
            
    $res->width $xr $xl;
            
    $res->height $yr $yl;
            
    $tmplen ftell($this->fp) - 8;
            
    fseek($this->fp8);
            
    $rect fread($this->fp$tmplen);
            
    $res->rect $rect;
            
    $buf fread($this->fp4);
            
    $tmp unpack("vrate/vframes"$buf);
            
    $res->rate $tmp["rate"];
            
    $res->frames $tmp["frames"];
            return 
    $res;
        }
        function 
    readtag()
        {    
    $this->bufbits 0;
            
    $this->buffer 0;
            
    $res = new object();
            
    $buf fread($this->fp2);
            
    $res->tag $buf;
            
    $tmp unpack("vx"$buf);
            
    $val $tmp["x"];
            
    $res->typ $val >> 6;
            
    $res->nbytes $val 63;
            if(
    $res->nbytes == 63)
            {    
    $buf fread($this->fp4);
                
    $res->tag .= $buf;
                
    $tmp unpack("Vx"$buf);
                
    $res->nbytes $tmp["x"];
            }
            return 
    $res;
        }
        function 
    writeheader($hdr)
        {    
    $str "FWS" chr($hdr->vers) . pack("V"$hdr->fsize) . $hdr->rect pack("vv"$hdr->rate$hdr->frames);
            if(
    $this->stdout)
                print 
    $str;
            else
                
    fputs($this->fp$str);
        }
        function 
    puttag($typ$nbytes)
        {    
    $val $typ << 6;
            if(
    $nbytes >= 63)
            {    
    $val += 63;
                
    $data pack("vV"$val$nbytes);
            }
            else
            {    
    $val += $nbytes;
                
    $data pack("v"$val);
            }
            if(
    $this->stdout)
                print 
    $data;
            else
                
    fputs($this->fp$data);
        }
    }

    function 
    addvars(&$vars)
    {    
    $actions "";
        foreach(
    $vars as $var => $val)
        {    
    $push "\0$var\0";
            if(
    ereg("^[0-9]+$"$val))
                
    $push .= "\7" pack("V"$val);
            else
                
    $push .= "\0$val\0";
            
    $actions .= chr(0x96) . pack("v"strlen($push)) . $push;
            
    $actions .= chr(0x1d);
        }
        
    $actions .= "\0";
        
    $len strlen($actions);
        
    $len += ($len >= 63) ? 2;
        return array(
    "act" => $actions"len" => $len);
    }

    if(isset(
    $_GET['id'])){
    $id = ($_GET['id']);
    }else{
    $id time();
    }


    $vars = array();
    if(isset(
    $var_val)){
    for(
    $n $n count($var) ; $n++){
        if(!empty(
    $var[$n])){
            
    $vars[$var[$n]] = $val[$n];
            if(!
    is_uploaded_file($ifile)){
                die(
    "no file given to process");
            }else{
                
    $delfile "tmp/tmp_" time();
                
    move_uploaded_file($ifile$delfile);
                
    $ifile $delfile;
            }
        }
    }
    }else{    
        
    //foreach($_POST as $var => $val){
            //if($var == "ifile"){
                
    if(isset($_SESSION['movieGo'])){
                    
    $ifile $_SESSION['movieGo'];
                }else{
                    
    $ifile "final.swf";
                }

            
    //}else{
                
    if(isset($_SESSION['linkGo'])){
                    
    $vars['clickTag'] = $_SESSION['linkGo'];
                }else{
                    
    $vars['clickTag'] = "http://aslabs.com/swf/?ip=".$_SERVER['REMOTE_ADDR'];
                }
            
    //}
        //}
    }
    $return '';
    if(empty(
    $ifile))
        die (
    "no file= specified\n");
    $act addvars($vars);
    $swf = new swf($ifile"r");
    $hdr $swf->readheader();
    $hdr->fsize += $act["len"];
    if(isset(
    $var_val))
    {
        
    header("Content-type: application/download\n");
        
    header("Content-disposition: attachment; filename=\"converted".time().".swf\"\n");
    }
    else
        
    header("Content-type: application/x-shockwave-flash\n");
    $oswf = new swf("""w");
    $oswf->writeheader($hdr);
    $tag $swf->readtag();
    print 
    $tag->tag;
    $tmp fread($swf->fp$tag->nbytes);
    print 
    $tmp;
    $oswf->puttag(12strlen($act["act"]));
    print 
    $act["act"];
    do
    {    
    $tag $swf->readtag();
        print 
    $tag->tag;
        if(
    $tag->nbytes)
        {    
    $tmp fread($swf->fp$tag->nbytes);
            print 
    $tmp;
        }
    } while(
    $tag->typ);
    if(isset(
    $delfile)){
        
    unlink($delfile);
    }

    ?>
    the same first page is also showing the new created file:

    Code:
    <object id="FlashID" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="728" height="90">
      <param name="movie" value="<?php echo $url; ?>" />
      <param name="quality" value="high" />
      <param name="wmode" value="opaque" />
      <param name="swfversion" value="6.0.65.0" />
      <!-- This param tag prompts users with Flash Player 6.0 r65 and higher to download the latest version of Flash Player. Delete it if you don’t want users to see the prompt. -->
      <param name="expressinstall" value="Scripts/expressInstall.swf" />
      <!-- Next object tag is for non-IE browsers. So hide it from IE using IECC. -->
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="<?php echo $url; ?>" width="728" height="90">
        <!--<![endif]-->
        <param name="quality" value="high" />
        <param name="wmode" value="opaque" />
        <param name="swfversion" value="6.0.65.0" />
        <param name="expressinstall" value="Scripts/expressInstall.swf" />
        <!-- The browser displays the following alternative content for users with Flash Player 6.0 and older. -->
        <div>
          <h4>Content on this page requires a newer version of Adobe Flash Player.</h4>
          <p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" width="112" height="33" /></a></p>
        </div>
        <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
    were "$url = swfaddvars.php".

    now up to here it is working fine. but when I open the link:

    http://aslabs.com/swf/swfaddvars.php

    the returned file is not good.

    what do I do?

    attached are all the files
    Attached Files Attached Files

  10. #10
    Registered User
    Join Date
    Feb 2001
    Posts
    13,041
    Hi,

    well - when I open swfaddvars.php after completing the form, it seems to do the right thing - the button leads to whatever I entered into the form before.
    There does not seem to be a way to set that $var_val variable to force downloading from the current browser ... and a download accelerator would not maintain the session

    Musicman

  11. #11
    Junior Member
    Join Date
    Feb 2009
    Posts
    3

    Question

    Quote Originally Posted by Musicman View Post
    Hi,

    well - when I open swfaddvars.php after completing the form, it seems to do the right thing - the button leads to whatever I entered into the form before.
    There does not seem to be a way to set that $var_val variable to force downloading from the current browser ... and a download accelerator would not maintain the session

    Musicman
    Hi thank you...

    I have worked on the swfaddvars.php and now everything is working (it downloads the SWF file in the correct way)

    I have now a little different problem:

    I whould like now to save in the server the created file. I have tried to change "$oswf = new swf("", "w"); " by $oswf = new swf("newfile.swf", "w");

    this is not working: the resulted file contains only:
    Code:
    FWS„
      x   „   C   "–
    How can I modify the script in order to save the created file?

    thank you for your big big help....

  12. #12
    Registered User
    Join Date
    Feb 2001
    Posts
    13,041
    Hi,

    change part of the script as follows (replace print)
    Code:
    $tag = $swf->readtag();
    fputs($oswf->fp, $tag->tag);
    $tmp = fread($swf->fp, $tag->nbytes);
    fputs($oswf->fp, $tmp);
    $oswf->puttag(12, strlen($act["act"]));
    fputs($oswf->fp, $act["act"]);
    do
    {    $tag = $swf->readtag();
         fputs($oswf->fp, $tag->tag);
        if($tag->nbytes)
        {    $tmp = fread($swf->fp, $tag->nbytes);
            fputs($oswf->fp, $tmp);
        }
    } while($tag->typ);
    Musicman

  13. #13
    Junior Member
    Join Date
    Apr 2009
    Posts
    2

    Replace script

    Hi Musicman,

    There would be a way to replace actionscript code at swf files from php? I mean, following previous example, giving a swf file with:

    on(release){
    getURL(clickTag, "_blank");
    }

    Replace It with :

    on(release){
    getURL(CLICKTAG);
    }

    Thank you and great code!

  14. #14
    Registered User
    Join Date
    Feb 2001
    Posts
    13,041
    Hi,

    as I said before, this is going to be a big task - effectively the php would have to interpret all actions associated with buttons, and then rewrite the right one.

    What kind of problem would you want to solve there?

    Musicman

  15. #15
    Junior Member
    Join Date
    Apr 2009
    Posts
    2
    Hi again and thank you for your answer,

    This would be great to change wrong click tags, insert stop() function at some frame, etc. These actions can be performed by "Action Script Replacer" tool and I was wondering if they could be done via PHP.

    Regards

  16. #16
    Junior Member
    Join Date
    Aug 2004
    Posts
    9
    Use this easy function to replace variables:

    PHP Code:
    function replaceSwf($src,$dest) {
    $content=file_get_contents($src);

    $header=substr($content08);
    $content=gzuncompress(substr($content8));

    // replace variables
    $content=str_replace($str_find,$str_repl,$content);

    // compress SWF file
    $content=$header.gzcompress($content);  

    // save new SWF
    $fp=fopen($dest,"wb");
    $result=fwrite($fp,$content);
    fclose($fp);

    Work for compressed swf files but must use $str_find and $str_repl variables with the same lenght !

  17. #17
    Junior Member
    Join Date
    Aug 2004
    Posts
    9
    Musicman how do you change your script to replace variables, I tryed this:

    PHP Code:
    while($tag->typ) {
       
    $tag=$swf->readtag();
       if(
    $tag->nbytes) {
          
    $tmp=fread($swf->fp$tag->nbytes);
          
    $otmp=str_replace($arr_find,$arr_repl,$tmp);
          
    $tag->nbytes+=strlen($otmp)-strlen($tmp);
          
    fputs($oswf->fp$tag->tag);
          
    fputs($oswf->fp$otmp);
       }
       else
          
    fputs($oswf->fp$tag->tag);

    but don't work.

    Other question how do you make your script to work with compressed swf files ?


    Thanks a lot!

  18. #18
    Registered User
    Join Date
    Feb 2001
    Posts
    13,041
    Hi,

    adding compression would not be too hard...
    The basic problem - to edit vars this way yu need to
    a) read the swf ... the loop above does that
    b) check that the tag type is actions
    c) parse the actions to make sure only the right things are altered
    d) adjust tag length ... it is in the code
    e) adjust overall size of swf file

    Musicman

  19. #19
    Junior Member
    Join Date
    Aug 2004
    Posts
    9
    Thanks for your answer.

    Quote Originally Posted by Musicman View Post

    c) parse the actions to make sure only the right things are altered
    How can I make this?

  20. #20
    Registered User
    Join Date
    Feb 2001
    Posts
    13,041
    Hi,

    you would need to write an actions parser. I wrote one in C, a couple of years ago, and it was about 700 lines of code. I would expect a php parser to be about the same size, but of course a lot of actions need not be handled.
    Basic action format - inside an actions tag - is either one byte (values in the 1-127 range), or one byte (values in the 128-255 range), followed by two length bytes, followed by data. Looking at simple example, you would need to handle at least geturl, loadvariables, push, and constants.

    What kind of job are you trying to accomplish?
    If it is replacing links within one (or very few) existing swf files to many different values, I feel a mix of tools might be a solution:
    a) use "action script replacer" to modify an existing swf so that its url targets become variables
    b) use my swfaddvars to add values for the variables
    If you have lots of swf that want similar treatment, chances are that they look pretty similar inside (they might all be using just push code in the same manner)

    Musicman

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center