使用sapnwrfc使SAP远程功能模块调用变得简单。

v0.1.1 2016-04-07 15:59 UTC

This package is not auto-updated.

Last update: 2024-09-14 19:09:27 UTC


README

使用sapnwrfc和PHP使SAP远程功能模块调用变得简单。

Latest Stable Version Total Downloads Latest Unstable Version License

法律声明

本文中提到的SAP和其他SAP产品和服务是SAP SE(或其附属公司)在德国和其他国家的商标或注册商标。

摘要

欢迎使用SapPhp包。此包不是连接器,它使用php-sapnwrfc扩展来处理客户端-服务器通信。此包旨在通过RFC调用提供处理大量数据提取的干净面向对象的接口。我的开发计划是通过PHP接口扩展此类以处理SAP FM(检查RfcReadTable接口)

这是一个早期版本,我期望您提出问题和错误,并可能给我一些建议。

安装

请确保已安装php-sapnwrfc扩展。

composer require avdaneidanut/sapphp

SAP系统详细信息

该包使用两种方法通过使用\SapPhp\Repository类解析文件来检索SAP系统详细信息(ashost、sysnr、描述和名称)。

  1. 解析saplogon.ini文件:C:/Users/{currentUser}/AppData/Roaming/SAP/Common/

  2. 解析包根目录中的sapphp.xml。

如果第一种方法失败或返回无结果,则将执行第二种方法。

连接到SAP

<?php

use SapPhp\Connection;
use SapPhp\Exceptions\BoxNotFoundException;

try {
	$connection = new Connection(
		'box', // SAP Box Name
		'user', // SAP Username
		'passwd', // SAP Password
		'500' // SAP Client Code
	);
} catch(sapnwrfcConnectionException $ex) {
	// Do something if login failed.
} catch(BoxNotFoundException $ex) {
	// Do something if box doesn't exist.
}

执行功能模块调用

让我们获取有关用户的详细信息

<?php

// ... connection

// Instantiate new Function Module interface.
$function = $connection->fm(
	'BAPI_USER_GET_DETAIL', // RFC Enable FM
	true // Parse result (trim all strings and decode GUIDs)
);

// Get function description.
print_r($function->description());

// Add import parameter.
// Will trigger an \SapPhp\Exceptions\ParamNotFoundException if param is not found in function description.
$function->param('USERNAME', 'USER');

// Perform function call and retrieve result.
$result = $function->invoke();

使用RFC_READ_TABLE FM获取有关用户的详细信息怎么样?让我们开始吧

<?php

// ... connection

$function = $connection->fm('RFC_READ_TABLE');

$function->param('QUERY_TABLE', 'USR01')
	->param('OPTIONS', [
		['TEXT' => 'BNAME = \'USER\' OR BNAME = \'USER2\' OR BNAME LIKE \'USER5*\'']
	])
	->param('ROWCOUNT', 5)
	->param('DELIMITER', '~')
;

$result = $function->invoke();

非常好,我们可以使用SQL语句查询表。此FM的结果很脏,使用explode和array_merge来修复它,对吗?

[
  "DATA" => [
    [
      "WA" => "500~USER2      ~                    ~    ~ ~H~K~1~ ~        ~   ~            ~ ~                    ~                    ~ ~ ~0",
    ],
    [
      "WA" => "500~USER5      ~                    ~    ~ ~H~K~1~ ~        ~   ~            ~ ~                    ~                    ~ ~ ~0",
    ],
    [
      "WA" => "500~USER55      ~                    ~    ~ ~H~K~1~ ~        ~   ~            ~ ~                    ~                    ~ ~ ~0",
    ],
  ],
  "FIELDS" => [
    [
      "FIELDNAME" => "MANDT",
      "OFFSET" => "000000",
      "LENGTH" => "000003",
      "TYPE" => "C",
      "FIELDTEXT" => "Client",
    ],
    [
      "FIELDNAME" => "BNAME",
      "OFFSET" => "000004",
      "LENGTH" => "000012",
      "TYPE" => "C",
      "FIELDTEXT" => "User Name in User Master Record",
    ],
    [
      "FIELDNAME" => "STCOD",
      "OFFSET" => "000017",
      "LENGTH" => "000020",
      "TYPE" => "C",
      "FIELDTEXT" => "Start menu (old, replaced by XUSTART)",
    ],
    [
      "FIELDNAME" => "SPLD",
      "OFFSET" => "000038",
      "LENGTH" => "000004",
      "TYPE" => "C",
      "FIELDTEXT" => "Spool: Output device",
    ],
    [
      "FIELDNAME" => "SPLG",
      "OFFSET" => "000043",
      "LENGTH" => "000001",
      "TYPE" => "C",
      "FIELDTEXT" => "Print parameter 1",
    ],
    [
      "FIELDNAME" => "SPDB",
      "OFFSET" => "000045",
      "LENGTH" => "000001",
      "TYPE" => "C",
      "FIELDTEXT" => "Print parameter 2",
    ],
    [
      "FIELDNAME" => "SPDA",
      "OFFSET" => "000047",
      "LENGTH" => "000001",
      "TYPE" => "C",
      "FIELDTEXT" => "Print parameter 3",
    ],
    [
      "FIELDNAME" => "DATFM",
      "OFFSET" => "000049",
      "LENGTH" => "000001",
      "TYPE" => "C",
      "FIELDTEXT" => "Date format",
    ],
    [
      "FIELDNAME" => "DCPFM",
      "OFFSET" => "000051",
      "LENGTH" => "000001",
      "TYPE" => "C",
      "FIELDTEXT" => "Decimal notation",
    ],
    [
      "FIELDNAME" => "HDEST",
      "OFFSET" => "000053",
      "LENGTH" => "000008",
      "TYPE" => "C",
      "FIELDTEXT" => "Host destination",
    ],
    [
      "FIELDNAME" => "HMAND",
      "OFFSET" => "000062",
      "LENGTH" => "000003",
      "TYPE" => "C",
      "FIELDTEXT" => "Default host client",
    ],
    [
      "FIELDNAME" => "HNAME",
      "OFFSET" => "000066",
      "LENGTH" => "000012",
      "TYPE" => "C",
      "FIELDTEXT" => "Default host user name",
    ],
    [
      "FIELDNAME" => "MENON",
      "OFFSET" => "000079",
      "LENGTH" => "000001",
      "TYPE" => "C",
      "FIELDTEXT" => "Automatic Start",
    ],
    [
      "FIELDNAME" => "MENUE",
      "OFFSET" => "000081",
      "LENGTH" => "000020",
      "TYPE" => "C",
      "FIELDTEXT" => "Menu name",
    ],
    [
      "FIELDNAME" => "STRTT",
      "OFFSET" => "000102",
      "LENGTH" => "000020",
      "TYPE" => "C",
      "FIELDTEXT" => "Start menu (old, replaced by XUSTART)",
    ],
    [
      "FIELDNAME" => "LANGU",
      "OFFSET" => "000123",
      "LENGTH" => "000001",
      "TYPE" => "C",
      "FIELDTEXT" => "Language",
    ],
    [
      "FIELDNAME" => "CATTKENNZ",
      "OFFSET" => "000125",
      "LENGTH" => "000001",
      "TYPE" => "C",
      "FIELDTEXT" => "CATT: Test status",
    ],
    [
      "FIELDNAME" => "TIMEFM",
      "OFFSET" => "000127",
      "LENGTH" => "000001",
      "TYPE" => "C",
      "FIELDTEXT" => "Time Format (12-/24-Hour Specification)",
    ],
  ],
  "OPTIONS" => [
    [
      "TEXT" => "TEXT' => 'BNAME = 'USER' OR BNAME = 'USER2' OR BNAME LIKE 'USER5*'",
    ],
  ],
]

但是等等,我们怎么使用具有查询构建器和解析结果的FunctionModule接口呢?

<?php

// ... connection

// fm method will check if RfcReadTable is an FunctionModule interface Class, if so will return a new instance.
$function = $connection->fm('RfcReadTable'); 

// Let's do the same thing as before.
$result = $function->table('usr01') // set the query table
	->where('bname', ['USER', 'USER5']) // add multiple where clause (simulating where in )
	->orWhere('bname', 'LIKE', 'USER5*') // add custom comparation operator
	->limit(5) // limit the result to 5 rows
	->get() // perform function call, parse the result and return a \Illuminate\Support\Collection object.
;

print_r($result->toArray());

结果是

[
	[
		"MANDT" => "500",
		"BNAME" => "USER2",
		"STCOD" => "",
		"SPLD" => "",
		"SPLG" => "",
		"SPDB" => "H",
		"SPDA" => "K",
		"DATFM" => "1",
		"DCPFM" => "",
		"HDEST" => "",
		"HMAND" => "",
		"HNAME" => "",
		"MENON" => "",
		"MENUE" => "",
		"STRTT" => "",
		"LANGU" => "",
		"CATTKENNZ" => "",
		"TIMEFM" => "0",
	],
	[
		"MANDT" => "500",
		"BNAME" => "USER5",
		"STCOD" => "",
		"SPLD" => "",
		"SPLG" => "",
		"SPDB" => "H",
		"SPDA" => "K",
		"DATFM" => "1",
		"DCPFM" => "",
		"HDEST" => "",
		"HMAND" => "",
		"HNAME" => "",
		"MENON" => "",
		"MENUE" => "",
		"STRTT" => "",
		"LANGU" => "",
		"CATTKENNZ" => "",
		"TIMEFM" => "0",
	],
	[
		"MANDT" => "500",
		"BNAME" => "USER55",
		"STCOD" => "",
		"SPLD" => "",
		"SPLG" => "",
		"SPDB" => "H",
		"SPDA" => "K",
		"DATFM" => "1",
		"DCPFM" => "",
		"HDEST" => "",
		"HMAND" => "",
		"HNAME" => "",
		"MENON" => "",
		"MENUE" => "",
		"STRTT" => "",
		"LANGU" => "",
		"CATTKENNZ" => "",
		"TIMEFM" => "0",
	],
]

查看RfcReadTableQueryBuilder方法。

QueryBuilder使用

<?php

$query->where('column', 'value') // Add WHERE clause
	->andWhere('column2,' 'value2') // AND logical operarator
	->orWhere('column3', '<>', 'value3') // OR logical operator
	->orWhere(function ($query) { // WHERE group
		$query->where('column11', 'value11')
			->andWhere('column22', 'value22');
	})
	->orWhere('column5', '<>', [1, 2, 3, 4]); // Simulate WHERE IN clause

前面的代码将生成以下SQL查询

	WHERE
		COLUMN = 'value' 
		AND
		COLUMN2 = 'value2'
		OR
		COLUMN3 <> 'value3'
		OR
		(
			COLUMN11 = 'value11'
			AND
			COLUMN22 = 'value22'
		)
		OR 
		(
			COLUMN5 <> '1'
			OR
			COLUMN5 <> '2'
			OR
			COLUMN5 <> '3'
			OR
			COLUMN5 <> '4'
		)

待办事项

  • 在一个Collection中聚合多个表的结果,并在多个表中共享相同的查询。
<?php

// ... connection & function

$rfcReadTable->table(['table1', 'table2', 'table3'], function($agregatter) {
	$aggregate->table('table1')
		->with('table2')
		->on('column')
		->as('aggregated_table');
	$aggregate->table('aggregated_table', 'table3')
		->on('column2');
})->where('column', 'value');
  • 添加更多FunctionModule接口,如RfcReadTable - 请发送建议!

支持

如果您在使用此包时发现任何问题,我将尽快帮助您。