ABI stands for application binary interface, it is the standard way to interact with contracts in the Ethereum ecosystem, both from outside the blockchain and for contract-to-contract interaction.
Data is encoded or decoded according to its type.
<?php 
use kornrunner\Keccak;
use Web3\Contracts\Types\{Address, Boolean, Bytes, DynamicBytes, Integer, Str, Uinteger};
use Web3\Contracts\Ethabi;
use Web3\Utils;
include_once "../libraries/vendor/autoload.php";
$ethAbi = new Ethabi(['address' => new Address,'bool' => new Boolean,'bytes' => new Bytes,'dynamicBytes' => new DynamicBytes,'int' => new Integer,'string' => new Str,'uint' => new Uinteger,]);
$hosts = ["https://mainnet.infura.io"=>"https://mainnet.infura.io","https://goerli.infura.io"=>"https://goerli.infura.io", "https://cloudflare-eth.com"=>"https://cloudflare-eth.com", "https://eth-mainnet.alchemyapi.io"=>"https://eth-mainnet.alchemyapi.io", "https://eth-ropsten.alchemyapi.io"=>"https://eth-ropsten.alchemyapi.io", "https://testnet-rpc.anisticnetwork.net"=>"https://testnet-rpc.anisticnetwork.net", "https://data-seed-prebsc-1-s2.binance.org:8545"=>"https://data-seed-prebsc-1-s2.binance.org:8545"];
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
	$ajaxData = [];
	if ($_GET['action'] == 'parse_abi' OR ($_GET['action'] == 'submit' AND isset($_POST['abi']))) {
		$ajaxData['functions'] = [];
		$blocks = json_decode($_POST['abi'], true);
		if (@count($blocks) > 0) {
			foreach($blocks as $block) {
				if ($block['type'] == 'function') {
					$ajaxData['functions'][] = $block['name'];
				}
			}
		} else {
			$errmsg .= "Invalid ABI.";
		}
		
		if ($_GET['ajax'] == '1') {
			if ($errmsg) {
				$ajaxData['error'] = $errmsg;
			} 
			
			die(json_encode($ajaxData));
		}
	} 
	
	if ($_GET['action'] == 'get_args' OR ($_GET['action'] == 'submit' AND isset($_POST['abi']) AND isset($_POST['function'])) ) {
		$ajaxData['args'] = [];
		$blocks = json_decode($_POST['abi'], true);
		
		if (@count($blocks) > 0) {
			foreach($blocks as $block) {
				
				if ($block['type'] == 'function' and $block['name'] == $_POST['function']) {					
					if ($block['inputs']) {
						foreach($block['inputs'] as $input) {
							$ajaxData['args'][] = $input['name'] .  " ({$input['type']})";
						}
					}
				}
			}
		}
		
		if ($_GET['ajax'] == '1') {
			if ($errmsg) {
				$ajaxData['error'] = $errmsg;
			} 
			
			die(json_encode($ajaxData));
		}
	}
}
include_once("html_iframe_header.php");
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
	try {
		
		if (!$_POST['function']) {
			throw new Exception("Function should not be blank.");
		}
		
		$_POST['args'] = is_array($_POST['args']) ? $_POST['args'] : [];
		
		$blocks = json_decode($_POST['abi'], true);
		$data = "";
		if (@count($blocks) > 0) {
			foreach($blocks as $block) {
				
				if ($block['type'] == 'function' and $block['name'] == $_POST['function']) {				
				
					$encoded = "";
					if ($block['inputs']) {
						$params = $values = [];
						
						foreach($block['inputs'] as $k => $input) {
							$params[] = $input['type'];
							
							if (substr($input['type'],-2) == "[]") {
								$values[] = json_decode($_POST['args'][$k],true);
							} else {
								$values[] = $_POST['args'][$k];
							}
						}
						
						$encoded = substr($ethAbi->encodeParameters($params, $values),2); //remove 0x prefix
					}
				
					$methodStr = Utils::jsonMethodToString($block);
					
					$data = $ethAbi->encodeFunctionSignature($methodStr).$encoded ;
					break;
				}
			}
		}
	?>
	   <div class="alert alert-success">
			<h6 class="mt-3">Data (Hex)</h6>
			<textarea class="form-control" rows="5" id="comment" readonly><?php echo $data;?></textarea>
			
		</div>
<?php 
	} catch (Exception $e) {
		$errmsg .= "Problem found. " . $e->getMessage();
	}
} 
if ($errmsg) {
?>
    <div class="alert alert-danger">
        <strong>Error!</strong> <?php echo $errmsg?>
    </div>
<?php
}
?>
<form id='this_form' action='?action=submit' method='post'>
	<div class="form-group">
        <label for="function">Function:</label>
        <select class="form-control" type='text' name='function' id='function' value='<?php echo $_POST['function']?>' onchange="
				var self = $(this);
				var form = self.closest('form');
				$('p#args_panel',form).empty();
				$('p#args_panel',form).html('');
				$.ajax({
					url: '?ajax=1&action=get_args', 
					type: 'post',
					data: $('#this_form :input'),
					success:function(result){
						
						try {
							j = eval('(' + result + ')');
							
							if ('error' in j && j.error.length>0) {
								var error = true;
							} else {
								var error = false;
							}
							
							if (!error) {
								
								var args = j.args;
								
								if (args.length > 0) {
									
									var x;    
									for (x in args) {
										$('p#args_panel',form).append('<div class=\'form-group\'>'+ args[x] +':<input class=\'form-control\' type=\'text\' name=\'args[]\'/></div>');
										
									}
									
								} else {
									$('p#args_panel',form).html('    No arguments');
								}
							} else {
								alert(j.error);
							}
						} catch(e) {
							alert('Invalid Json Format.');
						}
					},
					complete:function() {
					}
				});
				">
			
			
			<?php
			
			if (@count($ajaxData['functions']) > 0) {
			?>
				<option value=''>Please select ...</option>
				<?php
				foreach($ajaxData['functions'] as $function_name) {
					
					$optionSelected = $function_name == $_POST['function'] ? " selected='selected'" : "";
				?>
					<option value='<?php echo $function_name?>'<?php echo $optionSelected?>><?php echo $function_name?></option>
				<?php
				}
			} else {
			?>
				<option value="">Please load from ABI ...</option>
			<?php
			}
			?>
		</select>
    </div>
	
	<div class="form-group">
        <label for="args">Function Arguments:</label>
		<p id='args_panel'>
			
		</p>
    </div>
	
	<div class="form-group">
		<label for="gas_price">ABI:</label>
		
		<div class="input-group mb-3">
			<textarea class="form-control" rows="10" name='abi' id='abi'><?php echo $_POST['abi']?></textarea>
			<div class="input-group-append">
			 <input class="btn btn-success" type="button" value="Load" onclick="
				var self = $(this);
				self.val('...'); 
				
				var form = self.closest('form');
				
				$('select#function',form).empty();
				
				$.ajax({
					url: '?ajax=1&action=parse_abi', 
					type: 'post',
					data: $('#this_form :input'),
					success:function(result){
						
						try {
							j = eval('(' + result + ')');
							
							if ('error' in j && j.error.length>0) {
								var error = true;
							} else {
								var error = false;
							}
							
							if (!error) {
								
								var functions = j.functions;
								
								if (functions.length > 0) {
									
									
									$('select#function',form).append('<option value=\'\' selected=\'selected\'>Please select ...</option>');
									
									
									var x;    
									for (x in functions) {
										$('select#function',form).append('<option value=\''+functions[x]+'\'>'+functions[x]+'</option>');
									}
									
									
								}
							} else {
								
								$('select#function',form).prepend('<option value=\'\' selected=\'selected\'>Please load from ABI ...</option>');
								alert(j.error);
							}
						} catch(e) {
							
							$('select#function',form).prepend('<option value=\'\' selected=\'selected\'>Please load from ABI ...</option>');
							alert('Invalid Json Format.');
						}
					},
					complete:function() {
						self.val('Load');
					}
				});
				"/>
			</div>
		</div>
	</div>
	
    <input type='submit' class="btn btn-success btn-block"/>
</form>
<script>
<?php
if ($_GET['action'] == 'submit') {
	if (@count($ajaxData['args']) > 0) {
		foreach($ajaxData['args'] as $k=>$arg) {
		?>
			$('p#args_panel').append('<div class=\'form-group\'><?php echo $arg?>:<input class=\'form-control\' type=\'text\' name=\'args[]\' value=\'<?php echo $_POST['args'][$k]?>\'/></div>');
		<?php
		}
	} else {
	?>
		$('p#args_panel').html('    No arguments');
	<?php
	}
} 
?>
</script>
<?php
include_once("html_iframe_footer.php"); 		
	<?php 
use Web3\Contracts\Ethabi;
use Web3\Contracts\Types\{Address, Boolean, Bytes, DynamicBytes, Integer, Str, Uinteger};
include_once "../libraries/vendor/autoload.php";
$ethAbi = new Ethabi(['address' => new Address,'bool' => new Boolean,'bytes' => new Bytes,'dynamicBytes' => new DynamicBytes,'int' => new Integer,'string' => new Str,'uint' => new Uinteger,]);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
	$ajaxData = [];
	if ($_GET['action'] == 'parse_abi' OR ($_GET['action'] == 'submit' AND isset($_POST['abi']))) {
		$ajaxData['functions'] = [];
		$abiBlocks = json_decode($_POST['abi'], true);
		if (@count($abiBlocks) > 0) {
			foreach($abiBlocks as $abiBlock) {
				if ($abiBlock['type'] == 'function') {
					if (count($abiBlock['outputs']) > 0) {
						$ajaxData['functions'][] = $abiBlock['name'];
					}
				}
			}
		} else {
			$errmsg .= "Invalid ABI.";
		}
		
		if ($_GET['ajax'] == '1') {
			if ($errmsg) {
				$ajaxData['error'] = $errmsg;
			} 
			
			die(json_encode($ajaxData));
		}
	} 
}
include_once("html_iframe_header.php");
$results = [];
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
	try {
		
		if (!$_POST['function'] OR !$_POST['abi']) {
			throw new Exception("Abi with selected function is needed.");
		}
		$abiBlocks = json_decode($_POST['abi'], true);
		
		if (@count($abiBlocks) > 0) {
			foreach($abiBlocks as $abiBlock) {
				
				if ($abiBlock['type'] == 'function' and $abiBlock['name'] == $_POST['function']) {		
					$totalOutputs = count($abiBlock['outputs']);
					
					if ($totalOutputs) {
						$encoded = $_POST['response'];
						
						// Remove 0x prefix
						if (substr($encoded, 0, 2) === '0x') {
							$encoded = substr($encoded, 2);
						}
						
						if (strlen($encoded) != 64 * $totalOutputs) {
							throw new Exception("Response length is not valid.");
						}
						
						$decodeds = str_split($encoded, 64);
						foreach($decodeds as $k=> $decoded) {
							
							$result['name']  = $abiBlock['outputs'][$k]['name'];
							$result['type']  = $abiBlock['outputs'][$k]['type'];
							$result['hex']   = "0x". $decoded;
							$result['value'] = $ethAbi->decodeParameter($abiBlock['outputs'][$k]['type'], $decoded);
							
							$results[] = $result;
						}
					}
				}
			}
		}
	?>
    <div class="alert alert-success">
		<?php echo $totalOutputs?> outputs have been decoded.
	</div>
	<div class="table-responsive">
		<table class="table table-bordered">
			<tr><th>Name</th><th>Type</th><th>Hex</th><th>Decoded Value</th></tr>
			<?php
			foreach($results as $result) {
			?>
				<tr>
					<td><?Php echo $result['name']?></td>
					<td><?Php echo $result['type']?></td>
					<td><?Php echo $result['hex']?></td>
					<td><?Php echo $result['value']?></td>
				</tr>
			<?Php
			}
			?>
		</table>
	</div>
<?php 
	} catch (Exception $e) {
		$errmsg .= "Problem found. " . $e->getMessage();
	}
} 
if ($errmsg) {
?>
    <div class="alert alert-danger">
        <strong>Error!</strong> <?php echo $errmsg?>
    </div>
<?php
}
?>
<form id='this_form' action='?action=submit' method='post'>
	
	<div class="form-group">
        <label for="response">Response To Decode:</label>
        <input class="form-control" type='text' name='response' id='response' value='<?php echo $_POST['response']?>'>
		<small>You may get this response from <a href="eth_call.php" target='_blank'>Ethereum Eth Call</a> to decode.</small>
    </div>
	
	<div class="form-group">
        <label for="function">Function:</label>
        <select class="form-control" type='text' name='function' id='function' value='<?php echo $_POST['function']?>'>
			<?php
			
			if (@count($ajaxData['functions']) > 0) {
			?>
				<option value=''>Please select ...</option>
				<?php
				foreach($ajaxData['functions'] as $function_name) {
					
					$optionSelected = $function_name == $_POST['function'] ? " selected='selected'" : "";
				?>
					<option value='<?php echo $function_name?>'<?php echo $optionSelected?>><?php echo $function_name?></option>
				<?php
				}
			} else {
			?>
				<option value="">Please load from ABI ...</option>
			<?php
			}
			?>
		</select>
    </div>
	
	<div class="form-group">
		<label for="gas_price">ABI:</label>
		
		<div class="input-group mb-3">
			<textarea class="form-control" rows="10" name='abi' id='abi'><?php echo $_POST['abi']?></textarea>
			<div class="input-group-append">
			 <input class="btn btn-success" type="button" value="Load" onclick="
				var self = $(this);
				self.val('...'); 
				
				var form = self.closest('form');
				
				$('select#function',form).empty();
				
				$.ajax({
					url: '?ajax=1&action=parse_abi', 
					type: 'post',
					data: $('#this_form :input'),
					success:function(result){
						
						try {
							j = eval('(' + result + ')');
							
							if ('error' in j && j.error.length>0) {
								var error = true;
							} else {
								var error = false;
							}
							
							if (!error) {
								
								var functions = j.functions;
								
								if (functions.length > 0) {
									$('select#function',form).append('<option value=\'\' selected=\'selected\'>Please select ...</option>');
									
									var x;    
									for (x in functions) {
										$('select#function',form).append('<option value=\''+functions[x]+'\'>'+functions[x]+'</option>');
									}
									
									
								}
							} else {
								
								$('select#function',form).prepend('<option value=\'\' selected=\'selected\'>Please load from ABI ...</option>');
								alert(j.error);
							}
						} catch(e) {
							
							$('select#function',form).prepend('<option value=\'\' selected=\'selected\'>Please load from ABI ...</option>');
							alert('Invalid Json Format.');
						}
					},
					complete:function() {
						self.val('Load');
					}
				});
				"/>
			</div>
		</div>
	</div>
	
    <input type='submit' class="btn btn-success btn-block"/>
</form>
<?php
include_once("html_iframe_footer.php");