How do I upload an asset in Craft 3, via PHP
I finally figured out how to upload an asset, however I still don't understand why the insertFileByLocalPath has been removed.

/**
 * @param UploadedFile $uploadedFile
 * @param int $folderId
 * @return Asset
 * @throws BadRequestHttpException
 * @throws UploadFailedException
 */
protected static function uploadNewAsset(UploadedFile $uploadedFile, $folderId) {


    if (empty($folderId)) {
        throw new BadRequestHttpException('No target destination provided for uploading');
    }

    if ($uploadedFile === null) {
        throw new BadRequestHttpException('No file was uploaded');
    }

    $assets = Craft::$app-&gt;getAssets();

    if ($uploadedFile-&gt;getHasError()) {
        throw new UploadFailedException($uploadedFile-&gt;error);
    }

    // Move the uploaded file to the temp folder
    if (($tempPath = $uploadedFile-&gt;saveAsTempFile()) === false) {
        throw new UploadFailedException(UPLOAD_ERR_CANT_WRITE);
    }

    if (empty($folderId)) {
        throw new BadRequestHttpException('The target destination provided for uploading is not valid');
    }

    $folder = $assets-&gt;findFolder(['id' =&gt; $folderId]);

    if (!$folder) {
        throw new BadRequestHttpException('The target folder provided for uploading is not valid');
    }

    // Check the permissions to upload in the resolved folder.
    $filename = Assets::prepareAssetName($uploadedFile-&gt;name);

    $asset = new Asset();
    $asset-&gt;tempFilePath = $tempPath;
    $asset-&gt;filename = $filename;
    $asset-&gt;newFolderId = $folder-&gt;id;
    $asset-&gt;volumeId = $folder-&gt;volumeId;
    $asset-&gt;avoidFilenameConflicts = true;
    $asset-&gt;setScenario(Asset::SCENARIO_CREATE);

    $result = Craft::$app-&gt;getElements()-&gt;saveElement($asset);

    return $asset;
}


and then in my controller I can simply use

$service-&gt;uploadImage(UploadedFile::getInstanceByName('photo'), 1);