PHP throw exception to parent/calling code

How can I throw an exception at the the caller of a function instead of inside the called function. For example:

function a() {
  //code that throws 'Exception'
}

a(); <-- error should occur here as "Uncaught 'Exception'";

In java, you can:

function a() throws Execption {
  //code that throws exception
}

a(); <-- error will occur here instead of inside the function.

so that instead of having to have the try/catch in function a you “pass” the exception to where the function was called from.

I’m guessing it must be possible because the php mysqli function ‘mysqli_stmt::execute’ does this (https://www.php.net/manual/en/mysqli-stmt.execute.php).

The reason I’m trying to do this is I’m writing a php library file and I want the error to appear in my index.php file, not in the library.php file where the function is that I’ve called. For example:

index.php

include("library.php");
a();

library.php

function a() {
//code that throws error
}

How to send push notifications to multiple devices using Migrate from legacy FCM APIs to HTTP v1 in laravel?

i send fcm token in array format but i getting error “field”:”message”,”description”:”Invalid JSON payload received. Unknown name “tokens” at ‘message’: Cannot find field.”

$fields = [
           'message' => [
           'tokens' => $fcmIds,
           'notification' => $notificationData,
           'data' => $dataPayload,
            ],
          ];

i send like this FCM token in array format.

Calculate in php date 6 yeats and 30 days ago

I am beginner in php.

I have this code in php 8.1:

$date = date('Y-m-d', strtotime('-30 days'));
echo $date;

It’s work fine, but i need date 6 years and 30 days ago. How can i check it?
I need date calculate from now

Please help me.

AWS SignatureV4 – Request Signature sometimes does not match?

We are using AWS SignatureV4 to make requests to an API Gateway using the IAM authoriser and are finding that signing only works some of the time…

We are signing requests using the AWS SDK.

$credentials = new Credentials(env('AWS_ACCESS_KEY_ID', ''), env('AWS_SECRET_ACCESS_KEY', ''));
$signer = new SignatureV4('execute-api', env('AWS_DEFAULT_REGION', ''));
$request = $signer->signRequest($request, $credentials);

Here are two example requests which are being made. (I have redacted sensitive information. These fields are identical between requests)

https://[redacted].execute-api.eu-west-1.amazonaws.com/dev-ew1/api/v1/users?userId[]=34129&userId[]=2405&userType=student&oktaId=[redacted]
https://[redacted].execute-api.eu-west-1.amazonaws.com/dev-ew1/api/v1/users?userId[]=2405&userId[]=196624&userType=student&oktaId=[redacted]

The top request is signed correctly and is processed. The second request fails with the following message:

The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. 
Consult the service documentation for details.

The Canonical String for this request should have been
'GET
/dev-ew1/api/v1/users
oktaId=[redacted]&userId%5B%5D=196624&userId%5B%5D=2405&userType=student
host:[redacted].execute-api.eu-west-1.amazonaws.com
x-amz-date:20231218T101701Z
x-platform:messaging
x-platform-organisation:55

host;x-amz-date;x-platform;x-platform-organisation
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'

The String-to-Sign should have been
'AWS4-HMAC-SHA256
20231218T101701Z
20231218/eu-west-1/execute-api/aws4_request
3400b7c56695b319d050d264522b645bf19346449c2147768fc0ca10b36001cf'

Both the successful and the failing request have the same headers.

{
    "Host": [
        "[redacted].execute-api.eu-west-1.amazonaws.com"
    ],
    "X-Platform": [
        "messaging"
    ],
    "X-Platform-Organisation": [
        "55"
    ],
}

Both use the same AWS credentials. The failure is the same all the time. The only thing that changes is the URL. E.g.

-- Query 2405 - Works
https://[redacted].execute-api.eu-west-1.amazonaws.com/dev-ew1/api/v1/users?userId[]=2405&userType=student&oktaId=[redacted]

-- Query 196624 - Works
https://[redacted].execute-api.eu-west-1.amazonaws.com/dev-ew1/api/v1/users?userId[]=196624&userType=student&oktaId=[redacted]

-- Query 2405 + 196624 at the same time - Signing Error
https://[redacted].execute-api.eu-west-1.amazonaws.com/dev-ew1/api/v1/users?userId[]=2405&userId[]=196624&userType=student&oktaId=[redacted]

-- Query 2405 + 34129 at the same time and this works fine??
https://[redacted].execute-api.eu-west-1.amazonaws.com/dev-ew1/api/v1/users?userId[]=34129&userId[]=2405&userType=student&oktaId=[redacted]

We are using PHP8.1 and aws sdk 3.294.1

Any ideas on how to debug further and figure this out?

can i mix syntax blade and javascript to get path img?

I want get img path from my database in my script

const modalSelect = document.querySelector('#modal-select')
        const list = document.querySelectorAll('#modal-option')

        modalSelect.addEventListener('change', function(e) {
            const option = modalSelect.options[modalSelect.selectedIndex].text
            const imgOpt= '{{ $products->where('name', 'option')->get('image') }}'
            

            list.forEach((element, i) => {
                const valueList = element.value

                if (valueList == option) {
                    Swal.fire({
                        title: option[0].toUpperCase() + option.slice(1),
                        text: "Modal with a custom image.",
                        imageUrl: "imgOpt",
                        imageWidth: 400,
                        imageHeight: 200,
                        imageAlt: option + " image"
                    });
                }
            });
        })

I tried searching for data with where and mix with const option in my script, but it didn’t work, I don’t know how to combine it

Moodle 3.8.3 – 504 Gateway Timeout Error When Saving Courses

After migrating from SiteGround to AWS for our server, we’ve encountered a problem with saving Moodle courses. Despite adjusting the PHP timeout and making other necessary updates, we’re consistently facing a 504 Gateway Timeout error when attempting to save courses in the Moodle administration interface. This issue is impacting our workflow, and I’m seeking assistance to troubleshoot and resolve it. Currently, we are using Moodle version 3.8.3. Any guidance or insights you can provide would be greatly appreciated.

enter image description here

Preventing XSS on php echo input [duplicate]

I have these two lines of code:

echo ('<input id=cat[] name=cat[] class="element checkbox" type = "checkbox" value="'.$category->slug.'" />');
echo ('<label class="choice" for=cat[]>'.$category->name.'</label>');

How can I clean them to avoid any possible XSS?
I tried using htmlspecialchars but the result is that it shows the code on the browser page, as a string and does not replace the variables with the content.

Files larger than 50kb are not sent

A form has been set up on the site, the data from which is sent to the telegram bot. The PHP script is like this

<?php

echo $TOKEN;

error_reporting(E_ALL);
ini_set('display_errors', 1);

require 'vendor/autoload.php';

use DotenvDotenv;

// Specify the path to the directory where the .env file is located
$dotenvPath = __DIR__;

// Create an instance of Dotenv and load environment variables
$dotenv = Dotenv::createImmutable(dirname(__DIR__));
$dotenv->load();

// Get the token value
$TOKEN = $_ENV['TOKEN'];

// Telegram bot token and channel ID
$TELEGRAM_CHAT_ID = "-1002017740876";

// Check for the presence of a POST request
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // Collect data from the form
    $product = $_POST['product'];
    $name = $_POST['name'];
    $phone = $_POST['phone'];
    $email = $_POST['email'];
    $attachments = $_FILES['attachments'];
    $invoice = $_FILES['invoice'];

    // Save data to the database or file (depends on your requirements)

    // Send notification to Telegram
    $message = "<b>Promindustry</b>n";
    $message .= "<b>Product Name: </b>".$product." n";
    $message .= "<b>Sender: </b>".$name." n";
    $message .= "<b>Phone: </b>".$phone." n";
    $message .= "<b>Email: </b>".$email;

    file_get_contents("https://api.telegram.org/bot$TOKEN/sendMessage?chat_id=$TELEGRAM_CHAT_ID&parse_mode=html&text=".urlencode($message));

    // Function to send a file to Telegram
    function sendFileToTelegram($document, $caption = '') {
        global $TOKEN, $TELEGRAM_CHAT_ID;

        $url = "https://api.telegram.org/bot$TOKEN/sendDocument";
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, [
            'chat_id' => $TELEGRAM_CHAT_ID,
            'document' => new CURLFile($document['tmp_name'], $document['type'], $document['name']),
            'caption' => $caption
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $server_output = curl_exec($ch);
        curl_close($ch);
    }

    // Send files to Telegram
    if ($attachments['error'] == UPLOAD_ERR_OK) {
        sendFileToTelegram($attachments, 'Attachment: Signboard, part photo, other information');
    }
    if ($invoice['error'] == UPLOAD_ERR_OK) {
        sendFileToTelegram($invoice, 'Attachment: Details for invoicing');
    }

    // Send a response to the client (e.g., JSON response)
    echo json_encode([ "status" => "success", "message" => "Form submitted successfully!", ]);

} else {
    // Send a response to the client about the invalid request method
    echo json_encode(["status" => "error", "message" => "Invalid request method!"]);
}
?>

The problem is that everything works fine as long as the file is less than 50 kilobytes in size. As soon as the file is larger, the form is not sent.
I will be grateful for your help in solving this problem.

I tried to redo the script

PHP json_decode – quote formatting

I’m trying to decode a json string with json_decode($str, false). But the format is not correct.

{mDetailedState:CONNECTED,mExtraInfo:3gnet,mIsAvailable:true,mIsFailover:false,mIsMetered:true,mIsRoaming:false,mNetworkType:0,mReason:connected,mState:CONNECTED,mSubtype:13,mSubtypeName:LTE,mTypeName:MOBILE,CREATOR:android.net.NetworkInfo$1@41bcdce,stateMap:{IDLE=DISCONNECTED,SCANNING=DISCONNECTED,CONNECTING=CONNECTING,AUTHENTICATING=CONNECTING,OBTAINING_IPADDR=CONNECTING,CONNECTED=CONNECTED,SUSPENDED=SUSPENDED,DISCONNECTING=DISCONNECTING,DISCONNECTED=DISCONNECTED,FAILED=DISCONNECTED,BLOCKED=DISCONNECTED,VERIFYING_POOR_LINK=CONNECTING,CAPTIVE_PORTAL_CHECK=CONNECTING},describeContents:0,getDetailedState:CONNECTED,getExtraInfo:3gnet,getReason:connected,getState:CONNECTED,getSubtype:13,getSubtypeName:LTE,getType:0,getTypeName:MOBILE,isAvailable:true,isConnected:true,isConnectedOrConnecting:true,isFailover:false,isMetered:true,isRoaming:false,toString:[type:MOBILE[LTE],state:CONNECTED/CONNECTED,reason:connected,extra:3gnet,failover:false,available:true,roaming:false,metered:true]}

I guess it is because of the quote issue.

For key, I can add the quote back by (reference)

$json = preg_replace('/([{,])(s*)([A-Za-z0-9_-]+?)s*:/','$1"$3":',$json);

The result will be

{"mDetailedState":CONNECTED,"mExtraInfo":3gnet,"mIsAvailable":true,"mIsFailover":false,"mIsMetered":true,"mIsRoaming":false,"mNetworkType":0,"mReason":connected,"mState":CONNECTED,"mSubtype":13,"mSubtypeName":LTE,"mTypeName":MOBILE,"CREATOR":android.net.NetworkInfo$1@41bcdce,"stateMap":{IDLE=DISCONNECTED,SCANNING=DISCONNECTED,CONNECTING=CONNECTING,AUTHENTICATING=CONNECTING,OBTAINING_IPADDR=CONNECTING,CONNECTED=CONNECTED,SUSPENDED=SUSPENDED,DISCONNECTING=DISCONNECTING,DISCONNECTED=DISCONNECTED,FAILED=DISCONNECTED,BLOCKED=DISCONNECTED,VERIFYING_POOR_LINK=CONNECTING,CAPTIVE_PORTAL_CHECK=CONNECTING},"describeContents":0,"getDetailedState":CONNECTED,"getExtraInfo":3gnet,"getReason":connected,"getState":CONNECTED,"getSubtype":13,"getSubtypeName":LTE,"getType":0,"getTypeName":MOBILE,"isAvailable":true,"isConnected":true,"isConnectedOrConnecting":true,"isFailover":false,"isMetered":true,"isRoaming":false,"toString":[type:MOBILE[LTE],"state":CONNECTED/CONNECTED,"reason":connected,"extra":3gnet,"failover":false,"available":true,"roaming":false,"metered":true]}

But, this function cannot add quote back to the value. I am not familiar with regex. Any reference I can refer in order to add the quote back to value or any idea I can convert the json to array easier? Thanks

On Ethereum Goerli, using web3.php, sending a raw Transaction, I get “Transaction Error: invalid sender”

yes, I know that Goerli is being deprecated, but it still works on Quicknode. I also know the world is moving to js rpc, but php works too.

This is my transaction data:
transdata:

Array(
    [from] => 0x9f49b1261cf9de806908bc1f35b2c0763727acc8
    [to] => 0xB1B019a98E97B28134A268ed9f47620D63225980
    [value] => 0x16345785d8a0000
    [gas] => 0x22
    [gasPrice] => 0x1d
    [nonce] => 0x0
    [chainId] => 2
)

To avoid confusion:
1 – The gasPrice is obtained on a call to the node
2 – Nonce is also obtained on a call to the node
3 – The following function is used to determine the gas price limit:

function calculateGasPriceLimit($baseGasPrice, $multiplier = 1.2, $minimumLimit = 10){
    // Apply a multiplier to the base gas price
    $gasPriceLimit = bcmul($baseGasPrice, $multiplier);
    
    // Ensure a minimum gas price limit to avoid setting it too low
    $gasPriceLimit = max($gasPriceLimit, $minimumLimit);
    
    return $gasPriceLimit;
}

This is the serialized_trans: 0xf865801d2294B1B019a98E97B28134A268ed9f47620D6322598088016345785d8a00008027a01388dc0a117357ae6a9ee73c6304960c73936315d579c3d543ea83db5bd453e5a07e8fd1f6958936f367653a471cd35012c93f34577227d45aded3219cdb59fe9c

And the result of Ethereum Raw Transaction Decode on https://rawtxdecode.in/

  "chainId": "2",
  "type": "LegacyTransaction",
  "valid": true,
  "hash": "0xe1b152179da7be8b043ebeb1d636a392e5dace5983d896db5dc82f3598ca0e2d",
  "nonce": "0",
  "gasPrice": "25",
  "gasLimit": "21000",
  "from": "0x9f49B1261CF9de806908BC1F35b2C0763727ACC8",
  "to": "0xb1b019a98e97b28134a268ed9f47620d63225980",
  "v": "28",
  "r": "6eef88a779d0924d01581f3b3ea270b6de4f3b82ab743b2297e8babee46b8619",
  "s": "182671e8851802daab9b9856c9aae96fe24490384ac751f992c8d1577c813608",
  "value": "100000000000000000"

I am extremely frustrated by the lack of documentation and the poor error description on the ethereum network. Please, if someone can spot something wrong with any of this that might be able to help me solve this issue, I would greatly appreciate it.

Only one file transferred from html form with multiple option to PHP [duplicate]

Form:

   <form method="post" enctype="multipart/form-data">
      <input type="file" name="file" multiple>
      <input type="hidden" value="GALLUPLOAD" name="DO">
      <input type="submit" value="Upload Gallery Photos">
    </form>

Script:

echo "<pre>";
print_r($_FILES);
echo "</pre>";

Result

Array
(
    [file] => Array
        (
            [name] => 9.jpg
            [type] => image/jpeg
            [tmp_name] => /tmp/phphhER8w
            [error] => 0
            [size] => 269108
        )

)

Files was selected as:

"9.jpg" "0.jpg" "1.JPG" "2.jpg" "3.JPG" "4.JPG" "5.jpg" "6.jpg" "7.jpg" "8.JPG" 

So only first file go into array.

Getting PHP Warning:

foreach() argument must be of type array|object, string given in

foreach ($_FILES['file']['tmp_name'] as $key => $tmpName )

Full code, it works for single file upload, but stop working when i add foreach (

switch ($_POST['DO'])
{
    case "MAINUPLOAD":
        $relp="";
        $maxsize=800;
        $fn='/0.jpg';
        break;
    case "GALLUPLOAD":
        $relp='/gallery';
        $maxsize=1600;
        $fn='/' . time() . '.jpg';
        break;
}


    if(isset($_FILES['file'])) {
        $DirDestination = getcwd() . substr($user['PHOTODIR'], 2);
        echo "<BR> DirDestination ".$DirDestination;

        if (!file_exists($DirDestination))
            mkdir($DirDestination, 0777, true);
        if (!file_exists($DirDestination . '/gallery'))
            mkdir($DirDestination . '/gallery', 0777, true);

        $DirDestination = $DirDestination . $relp;
        echo "<BR> DirDestination ".$DirDestination;

        foreach ($_FILES['file']['tmp_name'] as $key => $tmpName )
        {
            echo "<BR> XXX";
            if( !empty( $_FILES[ 'file' ][ 'error' ][ $key ] ) )
            {
                echo "<BR> err ".$_FILES[ 'file' ][ 'error' ];
//                return false; // return false also immediately perhaps??
            }
            $check=can_upload($tmpName);
            echo "<BR> check ".$check;

                if ($check === true) {
                    echo "<BR> check ".$check;

                    $fileTempName = $_FILES['file']['tmp_name'][$key];
                    try {
                        $img = new Imagick($fileTempName);
                        $img->stripImage(); //"Removed EXIF data
                        if ($img->getImageWidth() > $img->getImageHeight()) {
                            $newWidth = $maxsize;
                            $newHeight = $maxsize * $img->getImageHeight() / $img->getImageWidth();
                        } else {
                            $newHeight = $maxsize;
                            $newWidth = $maxsize * $img->getImageWidth() / $img->getImageHeight();
                        }
                        $img->resizeImage($newWidth, $newHeight, imagick::FILTER_CATROM, 1);

                        $tile = new Imagick();
                        $tile->newImage($img->getImageWidth(), $img->getImageHeight(), 'transparent', 'png');
                        $watermarkx = new Imagick(getcwd() . '/cats/fflogo.png');
                        $watermarkx->resizeImage($newWidth / 2, $newWidth * $watermarkx->getImageHeight() / $watermarkx->getImageWidth() / 2, imagick::FILTER_CATROM, 1);
                        $img->compositeImage($watermarkx, imagick::COMPOSITE_ATOP, $newWidth - $watermarkx->getImageWidth(), $newHeight - $watermarkx->getImageHeight());
                        $img->writeImage($DirDestination .$fn);
                        $img->clear();
                        $img->destroy();
                    } catch (Exception $e) {
                        echo 'Exception caught: ', $e->getMessage(), "n";
                    }

                }
                else
                {
                    echo "<strong>$check</strong>";
                }

        }
    }

how to publish php package so it will download `”name/mypackage”: “dev-build”`

I have the access of a PHP Package called “name/mypackage”,

and in my local computer system there is a file called composer.json that looks like this,

{
    "require": {
        "name/mypackage": "dev-build"
    }
}

when i run composer install

it will show me this error Problem 1 - Root composer.json requires name/mypackage dev-build, found name/mypackage[dev-main] but it does not match the constraint.

So my question is what version should i use in publicly available name/mypackage package’s composer.json file

{
    "name": "name/mypackage",
    "version": "<WHAT_SHOULD_I_USE_HERE_SO_IT_WILL_DOWNLOADS_IN_MY_COMPUTER>",
    "description": "PHP Package",
    "type": "library",
    "license": "MIT",
    "authors": [
        {
            "name": "sachin"
        }
    ]
}

Thank You

How to properly make a triangle pseudo-element in a menu? [closed]

I want to insert a triangle pseudo-element into the menu, but for some reason it doesn’t fit where it should, I want to do something like this:

.row {
  padding: 0;
}

.container-fluid {
  padding: 0;
  margin: 0;
}

.top-nav_btn {
  display: none;
  width: 20px;
  height: 20px;
  background-color: transparent;
  border: none;
  font-size: 18px;
  position: absolute;
  right: 30px;
  top: -80px;
}

.top-nav_btn ::hover {
  cursor: pointer;
}

.top-nav {
  background-image: url(../img/background/header-1440.svg);
  position: relative;
  background-size: 100%;
  height: 104px;
  background-repeat: no-repeat;
}

.logo-header_green {
  position: relative;
  margin: 21px;
  width: 75px;
  height: 75px;
}

.logo-footer_white {
  width: 75px;
  height: 75px;
}

.top-nav_menu {
  list-style: none;
  margin: 0;
  padding: 31px 11px;
  display: flex;
  align-items: center;
  position: relative;
}

.top-nav_menu a {
  color: var(--active-text-color);
}

.top-nav_menu li {
  margin-right: 45px;
}

.top-nav_menu li a {
  text-transform: uppercase;
  text-decoration: none;
  font-weight: 700
}

.top-nav_menu li a::after {
  content: '';
  width: 100%;
  height: 3px;
  background-color: var(--active-block);
  display: block;
  transform: translateY(42px) scale(0);
  transition: all 0.2s;
}

.top-nav_menu li a:hover {
  text-decoration: none;
}

.top-nav_menu li a:hover::after {
  transform: translateY(42px) scale(1);
}

.sub-menu a {
  display: block;
  padding: 16px 32px;
  color: #000;
  font-size: 15px;
  line-height: 180%;
}

.sub-menu {
  list-style: none;
  position: absolute;
  z-index: 99999;
  top: 100%;
  left: 0;
  -webkit-transition: 0.5s ease-in-out;
  -moz-transition: 0.5s ease-in-out;
  -o-transition: 0.5s ease-in-out;
  transition: 0.5s ease-in-out;
  background: #fff;
  box-shadow: 0 0 17px rgba(178, 191, 204, .25);
}

.sub-menu li a::after {
  display: none;
}

.menu-item-has-children {
  width: 0;
  border: 4px solid transparent;
  border-bottom: none;
  border-top-color: #8a8383;
  content: '';
  vertical-align: middle;
  display: inline-block;
  position: relative;
  right: 5px;
}

.top-nav_menu .sub-menu {
  display: none;
}

.top-nav_menu li:hover .sub-menu {
  display: block;
}

.top-nav_contact {
  list-style: none;
  padding: 0;
  display: flex;
}

.top-nav_contact a {
  margin-right: 45px;
  color: var(--active-text-color);
}
<div class="top-nav">
  <div class="row justify-content-between align-items-center p-0 m-0">
    <div class="col-md-6 p-0 m-0">
      <ul id="top-nav_menu" class="top-nav_menu">
        <li id="menu-item-870" class="menu-item menu-item-type-post_type menu-item-object-page current-page-ancestor current-menu-ancestor current-menu-parent current-page-parent current_page_parent current_page_ancestor menu-item-has-children menu-item-870"><a>Программы обучения</a>
          <ul class="sub-menu">
            <li id="menu-item-899" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-896 current_page_item menu-item-899"><a href="" aria-current="page">Повышение квалификации</a></li>
            <li id="menu-item-900" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-900"><a href="">Переподготовка</a></li>
            <li id="menu-item-901" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-901"><a href="">Подготовка</a></li>
          </ul>
        </li>
      </ul>
    </div>
  </div>
</div>

I’ve already tried in different ways, but somehow I can’t do it, maybe I made a mistake somewhere in the selectors?

Uncaught ErrorException: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in even though I am checkng for nulll

I am getting following error on line 42 of my code. But strange thing is I am already checking for null and the actual error seems to be happening on line 44. How to fix this issue?

Error

Uncaught ErrorException: htmlspecialchars(): Passing null to parameter
#1 ($string) of type string is deprecated in /var/www/mysite/mypage.php:42

Code

while($row3 = mysqli_fetch_assoc($result3))
{
   $emailbody .= "<b>Keyword:</b> ". htmlspecialchars($row2["keyword"]) ."<br>";

   if(!is_null($row3["summary"]))     //line 42
   {
      $emailbody .= "<b>Summary:</b> ". htmlspecialchars($row3["summary"]) ."<br>";
   }
}