Skip to Content

As you can see the “Tasting the Mix of PHP and SAP” series has undergone a rather big change, from now on we’re going to use the OOP aproach of PHP 5. Why? Well it is considered the “better” approach, it is more organized and easier to read and mantain.

In this Weblog, I will be using my custom version of “RFC_READ_TABLE”, as SAP Note “382318” reminds I should not be using the delivered version of “RFC_READ_TABLE”.

ZRFC_TABLE_OPERATIONS_LINE

FUNCTION ZRFC_READ_TABLE.

*”—-


“Local interface:

*”  IMPORTING

*”     VALUE(QUERY_TABLE) LIKE  DD02L-TABNAME

*”     VALUE(DELIMITER) LIKE  SONV-FLAG DEFAULT SPACE

*”     VALUE(NO_DATA) LIKE  SONV-FLAG DEFAULT SPACE

*”     VALUE(ROWSKIPS) LIKE  SOID-ACCNT DEFAULT 0

*”     VALUE(ROWCOUNT) LIKE  SOID-ACCNT DEFAULT 0

*”  EXPORTING

*”     VALUE(ROW_COUNT) TYPE  I

*”  TABLES

*”      OPTIONS STRUCTURE  RFC_DB_OPT

*”      FIELDS STRUCTURE  RFC_DB_FLD

*”      DATA STRUCTURE  TAB512

*”      KEYS STRUCTURE  DD03P

*”  EXCEPTIONS

*”      TABLE_NOT_AVAILABLE

*”      TABLE_WITHOUT_DATA

*”      OPTION_NOT_VALID

*”      FIELD_NOT_VALID

*”      NOT_AUTHORIZED

*”      DATA_BUFFER_EXCEEDED

*”—-


  CALL FUNCTION ‘VIEW_AUTHORITY_CHECK’

       EXPORTING

            VIEW_ACTION                    = ‘S’

            VIEW_NAME                      = QUERY_TABLE

       EXCEPTIONS

            NO_AUTHORITY                   = 2

            NO_CLIENTINDEPENDENT_AUTHORITY = 2

            NO_LINEDEPENDENT_AUTHORITY     = 2

            OTHERS                         = 1.

  IF SY-SUBRC = 2.

    RAISE NOT_AUTHORIZED.

  ELSEIF SY-SUBRC = 1.

    RAISE TABLE_NOT_AVAILABLE.

  ENDIF.

  • —————————————————————–

  • find out about the structure of QUERY_TABLE

  • —————————————————————–

  DATA BEGIN OF TABLE_STRUCTURE OCCURS 10.

          INCLUDE STRUCTURE DFIES.

  DATA END OF TABLE_STRUCTURE.

  “DATA TABLE_HEADER LIKE X030L.

  DATA TABLE_TYPE TYPE DD02V-TABCLASS.

  CALL FUNCTION ‘DDIF_FIELDINFO_GET’

       EXPORTING

            TABNAME        = QUERY_TABLE

            LANGU          = SY-LANGU

       IMPORTING

            DDOBJTYPE      = TABLE_TYPE

       TABLES

            DFIES_TAB      = TABLE_STRUCTURE

       EXCEPTIONS

            NOT_FOUND      = 1

            INTERNAL_ERROR = 2

            OTHERS         = 3.

  IF SY-SUBRC <> 0.

    RAISE TABLE_NOT_AVAILABLE.

  ENDIF.

  IF TABLE_TYPE = ‘INTTAB’.

    RAISE TABLE_WITHOUT_DATA.

  ENDIF.

  • —————————————————————-

  • isolate first field of DATA as output field

  • (i.e. allow for changes to structure DATA!)

  • —————————————————————-

  DATA LINE_LENGTH TYPE I.

  FIELD-SYMBOLS  LENGTH LINE_LENGTH. “IN CHARACTER MODE.

  • —————————————————————-

  • if FIELDS are not specified, read all available fields

  • —————————————————————-

  DATA NUMBER_OF_FIELDS TYPE I.

  DESCRIBE TABLE FIELDS LINES NUMBER_OF_FIELDS.

  IF NUMBER_OF_FIELDS = 0.

    LOOP AT TABLE_STRUCTURE.

      MOVE TABLE_STRUCTURE-FIELDNAME TO FIELDS-FIELDNAME.

      APPEND FIELDS.

    ENDLOOP.

  ENDIF.

  • —————————————————————–

  • for each field which has to be read, copy structure information

  • into tables FIELDS_INT (internal use) and FIELDS (output)

  • —————————————————————–

  DATA: BEGIN OF FIELDS_INT OCCURS 10,

          FIELDNAME  LIKE TABLE_STRUCTURE-FIELDNAME,

          TYPE       LIKE TABLE_STRUCTURE-INTTYPE,

          DECIMALS   LIKE TABLE_STRUCTURE-DECIMALS,

          LENGTH_SRC LIKE TABLE_STRUCTURE-INTLEN,

          LENGTH_DST LIKE TABLE_STRUCTURE-LENG,

          OFFSET_SRC LIKE TABLE_STRUCTURE-OFFSET,

          OFFSET_DST LIKE TABLE_STRUCTURE-OFFSET,

        END OF FIELDS_INT,

        LINE_CURSOR TYPE I.

  LINE_CURSOR = 0.

  • for each field which has to be read …

  LOOP AT FIELDS.

    READ TABLE TABLE_STRUCTURE WITH KEY FIELDNAME = FIELDS-FIELDNAME.

    IF SY-SUBRC NE 0.

      RAISE FIELD_NOT_VALID.

    ENDIF.

  • compute the place for field contents in DATA rows:

  • if not first field in row, allow space for delimiter

    IF LINE_CURSOR <> 0.

      IF NO_DATA EQ SPACE AND DELIMITER NE SPACE.

        MOVE DELIMITER TO DATA+LINE_CURSOR.

      ENDIF.

      LINE_CURSOR = LINE_CURSOR + STRLEN( DELIMITER ).

    ENDIF.

  • … copy structure information into tables FIELDS_INT

  • (which is used internally during SELECT) …

    FIELDS_INT-FIELDNAME  = TABLE_STRUCTURE-FIELDNAME.

    FIELDS_INT-LENGTH_SRC = TABLE_STRUCTURE-INTLEN.

    FIELDS_INT-LENGTH_DST = TABLE_STRUCTURE-LENG.

    FIELDS_INT-OFFSET_SRC = TABLE_STRUCTURE-OFFSET.

    FIELDS_INT-OFFSET_DST = LINE_CURSOR.

    FIELDS_INT-TYPE       = TABLE_STRUCTURE-INTTYPE.

    FIELDS_INT-DECIMALS   = TABLE_STRUCTURE-DECIMALS.

  • compute the place for contents of next field in DATA rows

    LINE_CURSOR = LINE_CURSOR + TABLE_STRUCTURE-LENG.

    IF LINE_CURSOR > LINE_LENGTH AND NO_DATA EQ SPACE.

      RAISE DATA_BUFFER_EXCEEDED.

    ENDIF.

    APPEND FIELDS_INT.

  • … and into table FIELDS (which is output to the caller)

    FIELDS-FIELDTEXT = TABLE_STRUCTURE-FIELDTEXT.

    FIELDS-TYPE      = TABLE_STRUCTURE-INTTYPE.

    FIELDS-LENGTH    = FIELDS_INT-LENGTH_DST.

    FIELDS-OFFSET    = FIELDS_INT-OFFSET_DST.

    MODIFY FIELDS.

  ENDLOOP.

  • end of loop at FIELDS

  • —————————————————————–

  • read data from the database and copy relevant portions

  • into DATA

  • —————————————————————–

  • output data only if NO_DATA equals space (otherwise the

  • structure information in FIELDS is the only result of

  • the module)

  IF NO_DATA EQ SPACE.

    DATA: BEGIN OF WORK, BUFFER(30000), END OF WORK.

    FIELD-SYMBOLS:  WHERE (OPTIONS).

      IF SY-DBCNT GT ROWSKIPS.

  •   copy all relevant fields into DATA (output) table

        LOOP AT FIELDS_INT.

          IF FIELDS_INT-TYPE = ‘P’.

            ASSIGN COMPONENT FIELDS_INT-FIELDNAME

                OF STRUCTURE +FIELDS_INT-OFFSET_DST(FIELDS_INT-LENGTH_DST).

        ENDLOOP.

  •   end of loop at FIELDS_INT

        APPEND DATA.

        IF ROWCOUNT > 0 AND SY-DBCNT GE ROWCOUNT. EXIT. ENDIF.

      ENDIF.

    ENDSELECT.

  ENDIF.

  • —————————————————————–

  • Get the primary key fields

  • —————————————————————–

  DATA: NAME TYPE DDOBJNAME.

  MOVE QUERY_TABLE TO NAME.

  ROW_COUNT = SY-DBCNT.

  CALL FUNCTION ‘DDIF_TABL_GET’

       EXPORTING

            NAME          = NAME

            STATE         = ‘M’

            LANGU         = SY-LANGU

       TABLES

            DD03P_TAB     = KEYS

       EXCEPTIONS

            ILLEGAL_INPUT = 1

            OTHERS        = 2.

ENDFUNCTION.

   body

   #login

 

if(isset($_POST[‘LOG_IN’]) || (isset($_POST[‘Table’])))
{
if(!isset($_SESSION[“Server”]))
{
$_SESSION[“Server”] = $_POST[“Server”];
$_SESSION[“Sysnum”] = $_POST[“Sysnum”];
$_SESSION[“Client”] = $_POST[“Client”];
$_SESSION[“User”] = $_POST[“User”];
$_SESSION[“Pass”] = $_POST[“Pass”];
}

$Login = new Login();
$Log_Me = $Login->Log_In($_SESSION[“Server”],$_SESSION[“Sysnum”],$_SESSION[“Client”],
$_SESSION[“User”],$_SESSION[“Pass”]);
$RFC_Me = $Login->RFC_Connection($Log_Me);

ECHO “

“;
ECHO “

Please choose the operation you want to perform

“;
PRINT(“

“);
PRINT(“

SE11

SE16

“);
PRINT(”   “);
PRINT(“

“);
ECHO “Log Out“;
ECHO “

“;

}
else
{
$_SESSION = array();
session_destroy();

$Login = new Login();
$Login->Login_Page();
}

?>

Also, inside

index.php

we call

Operations.php

by using a simple form. We need it to choose what operation we want to perform,

SE11

or

SE16

.

!https://weblogs.sdn.sap.com/weblogs/images/48024/Choose_SE11_SE16.png|height=137|alt=image|width=537|src=https://weblogs.sdn.sap.com/weblogs/images/48024/Choose_SE11_SE16.png|border=0!

The

Operations.php

is going to call our two new classes.

Login_Class.php

   body

   #login

 

if(isset($_POST[“Chooser”]))
{
$Choose_Mode = $_POST[“Chooser”];
}
elseif(isset($_POST[“Choose_Mode”]))
{
$Choose_Mode = $_POST[“Choose_Mode”];
}

$Login = new Login();
$Log_Me = $Login->Log_In($_SESSION[“Server”],$_SESSION[“Sysnum”],$_SESSION[“Client”],
$_SESSION[“User”],$_SESSION[“Pass”]);
$RFC_Me = $Login->RFC_Connection($Log_Me);

switch ($Choose_Mode)
{
CASE SE11:
$SE11 = new SE11();

if(isset($_POST[‘Table’]))
{
$Table = $_POST[‘Table’];
$SE11->Show_Table($Table,$RFC_Me);
}
else
{
$SE11->Ask_for_Table($Choose_Mode);
}
BREAK;
CASE SE16:
$SE16 = new SE16();

if(isset($_POST[‘Table’]))
{
$Table = $_POST[‘Table’];
$SE16->Show_Table($Table,$RFC_Me);
}
else
{
$SE16->Ask_for_Table($Choose_Mode);
}
BREAK;
}

?>

Here are our two classes, they both use the method

Ask_for_Table

image

image

SE11.php

“;
PRINT(“

“);
PRINT(“
“);
PRINT(“
“);
PRINT(”   “);
PRINT(“

“);
ECHO “

“;
}

function Show_Table($Table,$RFC_Me)
{

$this->fce = saprfc_function_discover($RFC_Me, “ZRFC_READ_TABLE”);
IF (! $this->fce )
{
ECHO “The function module had failed.”;
EXIT;
}

$Table = STRTOUPPER($Table);

saprfc_import ($this->fce,”QUERY_TABLE”,$Table);
saprfc_import ($this->fce,”DELIMITER”,”/”);
saprfc_table_init ($this->fce,”KEYS”);

$rfc_rc = “”;

$rfc_rc = saprfc_call_and_receive ($this->fce);
if ($rfc_rc != SAPRFC_OK)
{
if ($rfc == SAPRFC_EXCEPTION )
echo (“Exception raised: “.saprfc_exception($this->fce));
else
echo (“Call error: “.saprfc_error($this->fce));
exit;
}

$key_row = saprfc_table_rows ($this->fce,”KEYS”);

for ($i=1; $i<=$key_row; $i++)
{
$KEYS = saprfc_table_read ($this->fce,”KEYS”,$i);
$FIELDNAME[$i] = $KEYS[‘FIELDNAME’];
$INTLEN[$i] = $KEYS[‘INTLEN’];
$DATATYPE[$i] = $KEYS[‘DATATYPE’];
$ROLLNAME[$i] = $KEYS[‘ROLLNAME’];
$SCRTEXT_M[$i] = $KEYS[‘SCRTEXT_M’];
}

ECHO “
“;
ECHO “Table: ” . $Table;
ECHO “

“;

ECHO “”;

ECHO “”;
ECHO “”;
ECHO “”;
ECHO “”;
ECHO “”;
ECHO “”;
ECHO “”;

for ($i=1; $i<=$key_row; $i++)
{
$KEY = saprfc_table_read ($this->fce,”KEYS”,$i);
ECHO “”;
ECHO “”;
ECHO “”;
ECHO “”;
ECHO “”;
ECHO “”;
ECHO “”;
}

ECHO “

Field Name

Internal Length

Data Type

Domain

Short Text

$FIELDNAME[$i]

$INTLEN[$i]

$DATATYPE[$i]

$ROLLNAME[$i]

$SCRTEXT_M[$i]

“;

ECHO “

“;
PRINT(“

“);
PRINT(“
“);
PRINT(”   “);
PRINT(“

“);
ECHO “

“;
}
}

?>

!https://weblogs.sdn.sap.com/weblogs/images/48024/Table_SE16.png|height=227|alt=image|width=443|src=https://weblogs.sdn.sap.com/weblogs/images/48024/Table_SE16.png|border=0!

SE16.php

“;
PRINT(“

“);
PRINT(“
“);
PRINT(“
“);
PRINT(”   “);
PRINT(“

“);
ECHO “Log Out“;
ECHO “

“;
}

function Show_Table($Table,$RFC_Me)
{

$this->fce = saprfc_function_discover($RFC_Me, “ZRFC_READ_TABLE”);
IF (! $this->fce )
{
ECHO “The function module had failed.”;
EXIT;
}

$Table = STRTOUPPER($Table);

saprfc_import ($this->fce,”QUERY_TABLE”,$Table);
saprfc_import ($this->fce,”DELIMITER”,”/”);
saprfc_table_init ($this->fce,”OPTIONS”);
saprfc_table_init ($this->fce,”FIELDS”);
saprfc_table_init ($this->fce,”DATA”);

$rfc_rc = “”;

$rfc_rc = saprfc_call_and_receive ($this->fce);
if ($rfc_rc != SAPRFC_OK)
{
if ($rfc == SAPRFC_EXCEPTION )
echo (“Exception raised: “.saprfc_exception($this->fce));
else
echo (“Call error: “.saprfc_error($this->fce));
exit;
}

$data_row = saprfc_table_rows ($this->fce,”DATA”);
$field_row = saprfc_table_rows ($this->fce,”FIELDS”);

ECHO “
“;
ECHO “Table: ” . $Table;
ECHO “

“;

ECHO “”;

ECHO “”;
for($i=1; $i<=$field_row ; $i++)
{
$FIELDS = saprfc_table_read ($this->fce,”FIELDS”,$i);
ECHO “”;
}
ECHO “”;

for ($i=1; $i<=$data_row; $i++)
{
$DATA = saprfc_table_read ($this->fce,”DATA”,$i);
$TEST = SPLIT(“/”,$DATA[‘WA’]);
$rem = $i % 2;
if($rem == 0)
{
ECHO “”;
}
else
{
ECHO “”;
}
for($j=0; $j<$field_row; $j++)
{
ECHO “”;
}
ECHO “”;
}

ECHO “

“;
ECHO $FIELDS[‘FIELDNAME’];
ECHO “

“;
ECHO $TEST[$j];
ECHO “

“;

ECHO “

“;
PRINT(“

“);
PRINT(“
“);
PRINT(”   “);
PRINT(“

“);
ECHO “

“;
}
}

?>

As you can see and read -:) we can organize every functionallity in classes and just call them from our PHP pages.

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply